C语言 并发编程

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

C语言 并发编程

炸毛疯兔   2022-05-28 我要评论

下面代码、思路等来源于b站郭郭 和CSAPP样例,同时希望大家好好读一下CSAPP的内容,真的讲的很好

1、按照指定的顺序输出

我们执行两个线程:foo1foo2

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

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们