线程间的互斥与同步

网友投稿 545 2022-05-30

生产者消费者问题(用于理解线程间互斥与同步的典型事例)

线程间互斥:对于临界资源区,同一时刻只能由一个线程访问。相当于仓库,生产好的产品入库时,就不能从仓库中取东西;从仓库中取东西时,就不能将生产好的产品入库。

线程间同步:有些线程需要有次序的运行,这时候就要用到进程间同步。相当于仓库,只有在仓库中的产品数量大于0时,从仓库中取产品的操作才能进行;只有在仓库中的产品数量小于总数时,新产品入库的操作才能进行。

线程间互斥:互斥锁

线程间同步:信号量

/************************************************************************* > File Name: pv.c > Author: LiYongjun > Mail: 1160606604@qq.com > Created Time: Mon 25 Feb 2019 02:10:47 PM CST ************************************************************************/ #include #include #include #include pthread_mutex_t mutex; //互斥锁,用于互斥,保护临界资源,同一时刻只能有一人操作仓库 sem_t empty, full; //信号量,用于同步,生产者消费者问题 int sum; void *t1_fun(void *arg) { while(1) { sem_wait(&full); //full - 1 pthread_mutex_lock(&mutex); //上锁 sum--; printf("thread 1, sum = %d\n", sum); sleep(1); pthread_mutex_unlock(&mutex); //解锁 sem_post(&empty); //wait + 1 } } void *t2_fun(void *arg) { while(1) { sem_wait(&empty); //empty - 1 pthread_mutex_lock(&mutex); //上锁 sum++; printf("thread 2, sum = %d\n", sum); sleep(3); pthread_mutex_unlock(&mutex); //解锁 sem_post(&full); //full + 1 } } int main(int argc, char *argv[]) { pthread_mutex_init(&mutex, NULL); //初始化互斥量 sem_init(&empty, 0, 5); //初始化信号量 sem_init(&full, 0, 0); pthread_t t1, t2; pthread_create(&t1, NULL, t1_fun, NULL); pthread_create(&t2, NULL, t2_fun, NULL); while(1) { sleep(10); } }

执行结果

[root@VM_0_14_centos test]# gcc pv.c -lpthread [root@VM_0_14_centos test]# ./a.out thread 2, sum = 1 thread 2, sum = 2 thread 2, sum = 3 thread 2, sum = 4 thread 2, sum = 5 thread 1, sum = 4 thread 1, sum = 3 thread 1, sum = 2 thread 1, sum = 1 thread 1, sum = 0 thread 2, sum = 1 thread 2, sum = 2 thread 2, sum = 3 thread 2, sum = 4 thread 2, sum = 5

可以看到,仓库中产品的数量永远介于0~5之间(5为仓库最大容量)。

注解:

1.互斥锁

pthread_mutex_init()

函数原型:int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);

pthread_mutex_init()函数是以动态方式创建互斥锁的,参数attr指定了新建互斥锁的属性。如果参数attr为空,则使用默认的互斥锁属性,默认属性为快速互斥锁 。

线程间的互斥与同步

pthread_mutex_lock()

当pthread_mutex_lock()返回时,该互斥锁已被锁定。线程调用该函数让互斥锁上锁,如果该互斥锁已被另一个线程锁定和拥有,则调用该线程将阻塞,直到该互斥锁变为可用为止。

pthread_mutex_unlock()

pthread_mutex_unlock()可释放mutex引用的互斥锁对象。

2.信号量

sem_init()

原型:int sem_init(sem_t *sem, int pshared, unsigned int value);

sem :指向信号量对象

pshared : 指明信号量的类型。不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享。

value : 指定信号量值的大小

sem_wait()

sem_wait是一个函数,也是一个原子操作,它的作用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法。也就是说,如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,将信号量的值将减到1。

如果对一个值为0的信号量调用sem_wait(),这个函数就会原地等待直到有其它线程增加了这个值使它不再是0为止。

sem_post()

sem_post是给信号量的值加上一个“1”,它是一个“原子操作”---即同时对同一个信号量做加“1”操作的两个线程是不会冲突的;而同 时对同一个文件进行读和写操作的两个程序就有可能会引起冲突。

任务调度

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:05 RDD
下一篇:带你研究研究华为首款鸿蒙汽车问界M5的智能家用充电桩
相关文章