• 12.3 进程和线程传递数据、多线程编程


      我们在进程中给线程传递数据,程序如下:

     1 #include <unistd.h>
     2 #include <sys/types.h>
     3 
     4 #include <stdlib.h>
     5 #include <stdio.h>
     6 #include <errno.h>
     7 #include <string.h>
     8 #include <pthread.h>
     9 /*
    10 int pthread_create(pthread_t *restrict thread,
    11            const pthread_attr_t *restrict attr,
    12            void *(*start_routine)(void*), void *restrict arg);
    13 */
    14 
    15 int g_num = 0;
    16 typedef struct _Teacher
    17 {
    18     char name[64];
    19     int age;
    20 }Teacher;
    21 
    22 void *start_routine(void *arg)
    23 {
    24     int i = 0;
    25     Teacher *pt = (Teacher *)arg;
    26     printf("name : %s
    ", pt->name);
    27     printf("age : %d
    ", pt->age);
    28     
    29     pthread_detach(pthread_self());
    30     
    31     printf("thread id = %lu
    ", pthread_self());
    32     
    33     for(i = 0; i < 10; i++)
    34     {
    35         printf("B");
    36         fflush(stdout);
    37     }
    38     
    39     sleep(3);
    40     
    41     printf("
    ");
    42     
    43     pthread_exit(NULL);
    44 }
    45 
    46 int main()
    47 {
    48     pthread_t thread;
    49     int i = 0;
    50     
    51     g_num = 10;
    52     
    53     Teacher t = {"zhang", 10};
    54     
    55     pthread_create(&thread, NULL, start_routine, &t);
    56     
    57     for(i = 0; i< 10; i++)
    58     {
    59         printf("A");
    60         fflush(stdout);
    61     }
    62     printf("
    ");
    63     
    64     pthread_join(thread, NULL);
    65     printf("child thread die
    ");
    66     
    67     return 0;
    68 }

    执行结果如下:

    从线程体中将数据传出来,通过pthread_exit函数,程序如下:

     1 #include <unistd.h>
     2 #include <sys/types.h>
     3 
     4 #include <stdlib.h>
     5 #include <stdio.h>
     6 #include <errno.h>
     7 #include <string.h>
     8 #include <pthread.h>
     9 /*
    10 int pthread_create(pthread_t *restrict thread,
    11            const pthread_attr_t *restrict attr,
    12            void *(*start_routine)(void*), void *restrict arg);
    13 */
    14 
    15 int g_num = 0;
    16 typedef struct _Teacher
    17 {
    18     char name[64];
    19     int age;
    20 }Teacher;
    21 
    22 void *start_routine(void *arg)
    23 {
    24     int i = 0;
    25     Teacher *pt = (Teacher *)arg;
    26     printf("name : %s
    ", pt->name);
    27     printf("age : %d
    ", pt->age++);
    28     
    29     pthread_detach(pthread_self());
    30     
    31     for(i = 0; i < 10; i++)
    32     {
    33         printf("B");
    34         fflush(stdout);
    35     }
    36     
    37     sleep(2);
    38     
    39     printf("
    ");
    40     
    41     pthread_exit(arg);
    42 }
    43 
    44 int main()
    45 {
    46     pthread_t thread;
    47     int i = 0;
    48     
    49     g_num = 10;
    50     
    51     Teacher t = {"zhang", 10};
    52     
    53     pthread_create(&thread, NULL, start_routine, &t);
    54     
    55     for(i = 0; i< 10; i++)
    56     {
    57         printf("A");
    58         fflush(stdout);
    59     }
    60     printf("
    ");
    61     
    62     Teacher *p = NULL;
    63     
    64     pthread_join(thread, (void **)&p);
    65     printf("name : %s
    ", p->name);
    66     printf("age : %d
    ", p->age);
    67     
    68     return 0;
    69 }

    第41行将arg传出来了(41行使用return arg是一样的),执行结果如下:

    注意:线程体函数中传出的数据不能是在线程体中的局部变量。

    一般情况下,线程的运算结果需要告诉父进程,即可用这种方法传出来。

    多线程编程:

     

    父进程传给每个子线程的地址空间必须是独立的,否则当多个线程访问这些地址空间时会造成相互影响,例如A空间传给了线程a,在主进程中修改A空间时,就会影响进程a。

    线程属性设置:

     POSIX线程锁:线程也可以用信号量作为锁,但是信号量动作太大,线程有自己的锁机制。

    多线程加锁的程序如下:

      1 #include <unistd.h>
      2 #include <sys/types.h>
      3 
      4 #include <stdlib.h>
      5 #include <stdio.h>
      6 #include <errno.h>
      7 #include <string.h>
      8 #include <pthread.h>
      9 /*
     10 int pthread_mutex_init(pthread_mutex_t *restrict mutex,
     11            const pthread_mutexattr_t *restrict attr);
     12        pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 
     13        
     14 int pthread_mutex_destroy(pthread_mutex_t *mutex);
     15        int pthread_mutex_init(pthread_mutex_t *restrict mutex,
     16            const pthread_mutexattr_t *restrict attr);
     17        pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
     18 */
     19 
     20 typedef struct _ThreadInfo
     21 {
     22     char id[100];
     23     int port;
     24     char name[64];
     25     int age;
     26     int numId;
     27 }ThreadInfo;
     28 
     29 int g_num = 0;
     30 int nNum;
     31 int nLoop;
     32 
     33 /*
     34 int pthread_mutex_lock(pthread_mutex_t *mutex);
     35        int pthread_mutex_trylock(pthread_mutex_t *mutex);
     36        int pthread_mutex_unlock(pthread_mutex_t *mutex);
     37 
     38 */
     39 
     40 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
     41 
     42 void *thread_routine(void *arg)
     43 {
     44     int i = 0;
     45     ThreadInfo *tmp = (ThreadInfo *)arg;
     46     pthread_mutex_lock(&mutex);
     47     
     48     printf("g_num : %d 
    ", g_num);
     49     sleep(1);
     50     printf("numId : %d 
    ", tmp->numId);
     51     
     52     pthread_mutex_unlock(&mutex);
     53     /*
     54     for(i = 0; i < nLoop; i++)
     55     {
     56         printf("thread id:%d  loop : %d  numid : %d 
    ", pthread_self(), i, tmp->numId);
     57     }
     58     */
     59     if(tmp != NULL)
     60     {
     61         free(tmp);
     62     }
     63     
     64     pthread_exit(0);
     65 }
     66 
     67 
     68 int main()
     69 {
     70     int i = 0;
     71     nNum = 10;
     72     nLoop = 10;
     73     
     74     pthread_t tidArray[200];
     75     g_num = 11;
     76     
     77     //pthread_mutex_init(&mutex, NULL);
     78     
     79     printf("enter the number of thread : 
    ");
     80     scanf("%d", &nNum);
     81     
     82     printf("enter thr loop : 
    ");
     83     scanf("%d", &nLoop);
     84     
     85     for (i = 0; i < nNum; i++)
     86     {
     87         ThreadInfo *p = (ThreadInfo *)malloc(sizeof(ThreadInfo));
     88         p->numId = i + 1;
     89         pthread_create(&tidArray[i], NULL, thread_routine, (void *)p);
     90     }
     91     
     92     for(i = 0; i < nNum; i++)
     93     {
     94         pthread_join(tidArray[i], NULL);
     95     }
     96     
     97     printf("end 
    ");
     98     
     99     return 0; 
    100 }

    第40行是锁的静态初始化,第77行是锁的动态初始化。

    执行结果如下:

    测试多线程的四种情况:

  • 相关阅读:
    【ST】lab01——Junit and Eclemma
    【SPM】hw1——个人房间装修
    【ST】hw2——find the error in the follow case
    【ST】Describe an error from my past projects
    ST homework4 --- 图覆盖
    ST lab1——Junit和覆盖测试的初探
    ST work12——failure,fault,error
    ST work1——印象最深的一个bug DJI 激活时报 SDK_ACTIVE_SDK_VERSION_ERROR
    C# note 06——delegate 和 event
    C# note 05——异常处理
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9452593.html
Copyright © 2020-2023  润新知