https://www.cnblogs.com/jiqingwu/p/linux_semaphore_example.html

信号量和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区,而信号量允许多个线程同时进入临界区。

不多做解释,要使用信号量同步,需要包含头文件semaphore.h。

主要用到的函数:

  • int sem_init(sem_t *sem, int pshared, unsigned int value);,其中sem是要初始化的信号量,pshared表示此信号量是在进程间共享还是线程间共享,value是信号量的初始值。
  • int sem_destroy(sem_t *sem);,其中sem是要销毁的信号量。只有用sem_init初始化的信号量才能用sem_destroy销毁。
  • int sem_wait(sem_t *sem);等待信号量,如果信号量的值大于0,将信号量的值减1,立即返回。如果信号量的值为0,则线程阻塞。相当于P操作。成功返回0,失败返回-1。
  • int sem_post(sem_t *sem); 释放信号量,让信号量的值加1。相当于V操作。

下列的代码演示了如何用信号量同步,模拟一个窗口服务系统。

/* @purpose: 基于信号量的多线程同步,操作系统原理中的P,V操作* @author: jollywing@foxmail.com* @create: 2015-03-20 Fri* */#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>/* @Scene: 某行业营业厅同时只能服务两个顾客。* 有多个顾客到来,每个顾客如果发现服务窗口已满,就等待,* 如果有可用的服务窗口,就接受服务。 *//* 将信号量定义为全局变量,方便多个线程共享 */
sem_t sem;/* 每个线程要运行的例程 */
void * get_service(void *thread_id)
{/* 注意:立即保存thread_id的值,因为thread_id是对主线程中循环变量i的引用,它可能马上被修改 */int customer_id = *((int *)thread_id);if(sem_wait(&sem) == 0) {usleep(100);                /* service time: 100ms */printf("customer %d receive service ...\n", customer_id);sem_post(&sem);}
}#define CUSTOMER_NUM 10int main(int argc, char *argv[])
{/* 初始化信号量,初始值为2,表示有两个顾客可以同时接收服务 *//* @prototype: int sem_init(sem_t *sem, int pshared, unsigned int value); *//* pshared: if pshared == 0, the semaphore is shared among threads of a process* otherwise the semaphore is shared between processes.   */sem_init(&sem, 0, 2);/* 为每个顾客定义一个线程id, pthread_t 其实是unsigned long int */pthread_t customers[CUSTOMER_NUM];int i, ret;/* 为每个顾客生成一个线程 */for(i = 0; i < CUSTOMER_NUM; i++){int customer_id = i;ret = pthread_create(&customers[i], NULL, get_service, &customer_id);if(ret != 0){perror("pthread_create");exit(1);}else {printf("Customer %d arrived.\n", i);}usleep(10);}/* 等待所有顾客的线程结束 *//* 注意:这地方不能再用i做循环变量,因为可能线程中正在访问i的值 */int j;for(j = 0; j < CUSTOMER_NUM; j++) {pthread_join(customers[j], NULL);}/* Only a  semaphore that  has been initialized  by sem_init(3)* should be destroyed using sem_destroy().*/sem_destroy(&sem);return 0;
}

编译:gcc main.c -lpthread

运行结果(注意,每次运行都不相同):

Customer 0 arrived.
Customer 1 arrived.
customer 0 receive service ...
Customer 2 arrived.
customer 1 receive service ...
Customer 3 arrived.
customer 2 receive service ...
Customer 4 arrived.
customer 3 receive service ...
Customer 5 arrived.
customer 4 receive service ...
Customer 6 arrived.
customer 5 receive service ...
Customer 7 arrived.
customer 6 receive service ...
Customer 8 arrived.
customer 7 receive service ...
Customer 9 arrived.
customer 8 receive service ...
customer 9 receive service ...

Linux 线程信号量同步相关推荐

  1. Linux线程的同步,linux线程同步

    我是linux和linux线程的新手.我花了一些时间谷歌搜索试图理解可用于线程同步的所有函数之间的差异.我还有一些问题. 我找到了所有这些不同类型的同步,每个同步都有许多锁定,解锁,测试锁等功能. & ...

  2. 50.Linux 线程三 同步

    Linux系统中常用实现线程同步的方式有三种,分别为互斥锁.条件变量与信号量. 下面将对这三种方式逐一进行讲解. 4.1 互斥锁 使用互斥锁实现线程同步时,系统会为共享资源添加一个称为互斥锁的标记,防 ...

  3. linux线程间同步(1)互斥锁与条件变量

    线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量以及读写锁. 互斥锁(mutex) 互斥锁,是一种信 ...

  4. linux线程间同步(1)读写锁

    读写锁比mutex有更高的适用性,可以多个线程同时占用读模式的读写锁,但是只能一个线程占用写模式的读写锁. 1. 当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞: 2 ...

  5. c++ linux 线程等待与唤醒_Linux线程同步(互斥量、信号量、条件变量、生产消费者模型)...

    为什么要线程同步? 线程间有很多共享资源,都对一个共享数据读写操作,线程操作共享资源的先后顺序不确定,可能会造成数据的冲突 看一个例子 两个线程屏行对全局变量count++ (采用一个val值作为中间 ...

  6. Linux多线程——使用信号量同步线程

    http://blog.csdn.net/ljianhui/article/details/10813469/ 信号量.同步这些名词在进程间通信时就已经说过,在这里它们的意思是相同的,只不过是同步的对 ...

  7. Linux多线程编程---线程间同步(互斥锁、条件变量、信号量和读写锁)

    本篇博文转自http://zhangxiaoya.github.io/2015/05/15/multi-thread-of-c-program-language-on-linux/ Linux下提供了 ...

  8. Linux——线程同步(条件变量、POSIX信号量)和线程池

    一.线程同步 (一).概念 线程同步是一种多线程关系,指的是线程之间按照特定顺序访问临界资源,进而能够避免线程饥饿问题. 所谓线程饥饿指的是某个线程长期"霸占"临界资源,导致其他线 ...

  9. Linux多线程的同步-----信号量和互斥锁

    前面两篇给基本概念讲过了,大家有兴趣的可以去看一下: Linux多线程_神厨小福贵!的博客-CSDN博客进程和线程的区别有哪些呢?进程是资源分配的最小单位,线程是CPU调度的最小单位进程有自己的独立地 ...

最新文章

  1. 【收藏】docker的privileged 与 k8s的privileged 设置方式
  2. 新氧科技成为互联网医疗美容第一股 首日股价疯狂上涨32%
  3. flinkCdc的mysql配置及java测试代码
  4. Android Studio 2.3报错: Error:Cause: buildToolsVersion is not specified解决
  5. 运输层(UDP)详解(一)
  6. 从零开始实现Adam优化算法
  7. 【房价预测】基于matlab Elman神经网络房价预测【含Matlab源码 589期】
  8. java+ssm+mysql房屋租赁管理系统(源码+论文)
  9. Win10使用以前的图片查看器
  10. win7桌面运行html,win7系统多桌面切换的解决方案
  11. win7 64位系统加载dsoframer.ocx问题解决方法
  12. 全栈式PHP集成环境-laragon(二) 配置、使用
  13. python提取excel指定关键词的行数据
  14. Gem Port和T-CONT实现业务复用
  15. [问题解决] socket 10053
  16. SQLServer uniqueidentifier 类型
  17. python绘制柱状条形图
  18. 【转载】Linux常用命令大全之文件处理命令(一)
  19. oracle 11g rac suse,suse linux 11 + 多路径+udev+oracle11g rac
  20. C语言简介之进制转换,原码、反码、补码,位运算符,函数

热门文章

  1. 解决阿里云OSS跨域问题
  2. jQuary总结11:jQuery插件封装---jQuery封装 手风琴 动画插件
  3. 【BZOJ】3575: [Hnoi2014]道路堵塞
  4. Daily Scrum 11.18
  5. Oracle数据库的备份
  6. 从MySQL导入导出大量数据的程序实现方法
  7. 乐刻运动 app android,乐刻运动
  8. html option ajax,Ajax实现简单下拉选项效果【推荐】
  9. mysql为什么不能插入数据_mysql为啥不能插入数据
  10. 高校c语言题库,C语言-中国大学mooc-题库零氪