C语言 并发编程
炸毛疯兔 人气:0下面代码、思路等来源于b站郭郭 和CSAPP样例,同时希望大家好好读一下CSAPP的内容,真的讲的很好
1、按照指定的顺序输出
我们执行两个线程:foo1 和foo2
foo1:打印step1, step3
foo2:打印step2
请用并发使得按照1 2 3 的顺序输出
答:首先两个线程执行顺序不可预判,我们必须保证打印step2之前step1就打印好了,因此需要阻塞一下step2,实现的方式是初始化sem为0,只有打印完step1后(然后进行解锁,V操作)step2才能执行
同理,只有打印完step2后才解开阻塞step3的锁,具体看代码实现就明白了
#include "csapp.c" sem_t step1_done, step2_done; void* foo1() { printf("test1 is done\n"); V(&step1_done); //step1执行完毕了,那么foo2的阻塞就会被解开 P(&step2_done); //测试是否step2执行完毕, printf("test3 is done\n"); return NULL; } void* foo2() { P(&step1_done); printf("test2 is done\n"); V(&step2_done); //step2执行完毕,解开打印step的锁 return NULL; } int main() { pthread_t tid1, tid2; Sem_init(&step1_done, 0, 0); //第二个参数为0:在线程之间进行, 第三个参数初始化都为零 Sem_init(&step2_done, 0, 0); Pthread_create(&tid1, NULL, foo1, NULL); Pthread_create(&tid2, NULL, foo2, NULL); //保证线程执行完毕之后主线程才退出,否则线程都执行不了了 Pthread_join(tid1, NULL); Pthread_join(tid2, NULL); exit(0); }
2、生产者消费者模型
主要的就是在生产和消费函数中对于信号量的处理
错误实例:
void sbuf_insert(subf_t* sp, int item) { sem_wait(&sp->mutex); sem_wait(&sp->slots); //将项目放进buf中 sp->buf[(++sp->rear) % (sp->n)] = item; sem_post(&sp->items); sem_post(&sp->mutex); } void sbuf_remove(sbuf_t* sp) { sem_wait(&sp->mutex); sem_wait(&sp->items); //do works sem_post(&sp->slots); sem_post(&sp->mutex); }
如果我们在处理的时候先拿到 互斥锁,可能就会引起死锁
假设现在buf是满的,生产者拿到了互斥锁,但是自己因为没有空闲被 block…
此时消费者同样因为拿不到互斥锁而被 block…
其他的生产者同样也是没有 互斥锁被block…
解决方法:
比较简单,调换一下顺序就好了。相当于我们生产者、消费者在进行的时候 明确我到底要操控哪个格子 然后再拿mutex
加载全部内容