使用mutex
和条件变量对比
问题
学生线程写作业,老师线程检查作业。要求:只有学生线程写完作业了,老师线程才能检查作业。
- 使用
mutex
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #include "apue.h" #include <pthread.h>
int finished = 0; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void *do_homework(void *arg) { sleep(5);
pthread_mutex_lock(&lock); finished = 1; pthread_mutex_unlock(&lock); }
void *check_homework(void *arg) { sleep(1); pthread_mutex_lock(&lock); printf("老师:作业写完了吗\n"); while (finished == 0) { printf("学生:没有写完\n"); pthread_mutex_unlock(&lock); printf("老师:好的,你接着写\n"); printf("-------\n"); sleep(1); pthread_mutex_lock(&lock); printf("老师:作业写完了吗?\n"); } printf("学生写完了\n"); pthread_mutex_unlock(&lock); printf("老师开始检查\n"); } int main(int argc,char *argv[]) { pthread_t tid1,tid2; pthread_create(&tid1,NULL,do_homework,NULL); pthread_create(&tid2,NULL,check_homework,NULL);
pthread_join(tid1,NULL); pthread_join(tid2,NULL); exit(0); }
|
- 使用
mutex
配合条件变量(条件+变量)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #include "apue.h" #include <pthread.h>
int finished = 0; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void * do_homework(void *arg) { sleep(5); pthread_mutex_lock(&lock); finished = 1; pthread_mutex_unlock(&lock); pthread_cond_signal(&cond); printf("发送条件信号\n"); }
void *check_homework(void *arg) { sleep(1); pthread_mutex_lock(&lock); printf("老师: 作业写完了吗?\n"); while (finished == 0) { printf("学生: 没有写完\n"); printf("老师: 接着写\n"); printf("------------\n"); pthread_cond_wait(&cond,&lock); printf("老师: 作业写完了吗?\n"); } printf("学生: 写完了\n"); pthread_mutex_unlock(&lock); printf("老师开始检查\n"); } int main(int argc,char *argv[]) { pthread_t tid1,tid2; pthread_create(&tid1,NULL,do_homework,NULL); pthread_create(&tid2,NULL,check_homework,NULL); pthread_join(tid1,NULL); pthread_join(tid2,NULL); exit(0); }
|
- 相比使用互斥量的优点,不在进行轮询,第一次询问后开始睡眠,直到线程唤醒
例题:
4 个线程,线程 1 循环打印 A, 线程 2 循环打印 B, 线程 3 循环打印 C, 线程 4 循环打印 D. 输出ABCD ABCD ......
(非标准答案,但我不是通过时间控制执行顺序)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| #include "apue.h" #include <pthread.h>
typedef void *(*Func)(void *);
int all = 0; int c[5]; pthread_cond_t cond[5]; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void * thread1(void *arg) { while (1) { pthread_mutex_lock(&lock); while (c[1] == 0) { pthread_cond_wait(&cond[1],&lock); printf("A"); c[1] = 1; c[2] = 0; } pthread_mutex_unlock(&lock); pthread_cond_signal(&cond[2]); } }
void * thread2(void *arg) { while (1) { pthread_mutex_lock(&lock); while (c[2] == 0) { pthread_cond_wait(&cond[2],&lock); printf("B"); c[2] = 1; c[3] = 0; } pthread_mutex_unlock(&lock); pthread_cond_signal(&cond[3]); } }
void * thread3(void *arg) { while (1) { pthread_mutex_lock(&lock); while (c[3] == 0) { pthread_cond_wait(&cond[3],&lock); printf("C"); c[3] = 1; c[4] = 0; } pthread_mutex_unlock(&lock); pthread_cond_signal(&cond[4]); } }
void * thread4(void *arg) { while (1) { pthread_mutex_lock(&lock); while (c[4] == 0) { pthread_cond_wait(&cond[4],&lock); printf("D"); if (++all == 4) pthread_exit(NULL); c[4] = 1; c[1] = 0; } pthread_mutex_unlock(&lock); pthread_cond_signal(&cond[1]); } }
int main(int argc,char *argv[]) { setbuf(stdout,NULL); pthread_t tid[5]; Func func[5] = {NULL,thread1,thread2,thread3,thread4}; for (int i=1; i<=4; i++) cond[i] = (pthread_cond_t)PTHREAD_COND_INITIALIZER; for (int i=1; i<=4; i++) pthread_create(&tid[i],NULL,func[i],NULL);
pthread_cond_signal(&cond[1]);
for (int i=1; i<=4; i++) pthread_join(tid[i],NULL); exit(0); }
|