交替打印子线程的线程ID
主线程产生两个子线程,交替打印出各自的线程ID:
1 #include <stdio.h> 2 #include <pthread.h> 3 #include <stdlib.h> 4 5 static int flag=0;/*0-print thread 1, 1-print thread 2*/ 6 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 7 static pthread_mutex_t mutx = PTHREAD_MUTEX_INITIALIZER; 8 9 static void *printThreadId1(void *args) 10 { 11 int i = 0, iThreadNo = 0; 12 13 iThreadNo = (int)args; 14 15 while(i<10) 16 { 17 pthread_mutex_lock(&mutx); 18 19 if(flag != 0) 20 { 21 pthread_cond_wait(&cond,&mutx); 22 } 23 if(flag == 0) 24 { 25 pthread_cond_signal(&cond); 26 } 27 28 printf("Thread No.%d:%d\n",iThreadNo, pthread_self()); 29 30 i++; 31 flag = 0; 32 33 pthread_mutex_unlock(&mutx);
34 } 35 36 } 37 38 static void *printThreadId2(void *args) 39 { 40 int i = 0, iThreadNo = 0; 41 42 iThreadNo = (int)args; 43 44 while(i<10) 45 { 46 pthread_mutex_lock(&mutx); 47 48 if(flag != 1) 49 { 50 pthread_cond_wait(&cond,&mutx); 51 } 52 if(flag == 1) 53 { 54 pthread_cond_signal(&cond); 55 } 56 57 printf("Thread No.%d:%d\n",iThreadNo, pthread_self()); 58 59 i++; 60 flag = 0; 61 62 pthread_mutex_unlock(&mutx);
63 } 64 65 } 66 67 int main() 68 { 69 pthread_t tid1, tid2; 70 71 if(pthread_create(&tid1,NULL, printThreadId1 , (void *)1) != 0) 72 { 73 return EXIT_FAILURE; 74 } 75 76 if(pthread_create(&tid2,NULL, printThreadId2 , (void *)2) != 0) 77 { 78 return EXIT_FAILURE; 79 } 80 81 if(pthread_join(tid1, NULL) != 0) 82 { 83 return EXIT_FAILURE; 84 } 85 if(pthread_join(tid2, NULL) != 0) 86 { 87 return EXIT_FAILURE; 88 } 89 90 pthread_mutex_destroy(&mutx); 91 pthread_cond_destroy(&cond); 92 93 return EXIT_SUCCESS; 94 }
子线程对全局数据写操作的时候加互斥锁,线程打印线程id后,修改flag,转换执行权。
【注意】
条件变量和互斥锁变量mutex都是结合在一起使用,当多个线程pthread_cond_wait函数阻塞在同一个mutex锁的时候,要注意在pthread_cond_signal发送唤醒信号后,同时也需要对mutex进行解锁
APUE中对pthread_cond_wait的解释:
【pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)函数传入的参数mutex用于保护条件,因为我们在调用pthread_cond_wait时,如果条件不成立我们就进入阻塞,但是进入阻塞这个期间,如果条件变量改变了的话,那我们就漏掉了这个条件。因为这个线程还没有放到等待队列上,所以调用pthread_cond_wait前要先锁互斥量,即调用pthread_mutex_lock(),pthread_cond_wait在把线程放进阻塞队列后,自动对mutex进行解锁,使得其它线程可以获得加锁的权利。这样其它线程才能对临界资源进行访问并在适当的时候唤醒这个阻塞的进程。当pthread_cond_wait返回的时候又自动给mutex加锁。】
pthread_cond_wait对条件不成立的时候,会自动对mutex解锁,然后睡眠等待条件发生的信号,等到信号后,pthread_cond_wait第一个操作还是会先将mutex加锁