Linux 线程信号量同步

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 ...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383887.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

本原勾股数组

勾股数我们都很熟悉&#xff0c;a2b2c2&#xff0c;可是如何快速找到所有的勾股数组呢&#xff1f; 本原勾股数组a2b2c2性质&#xff1a; 1. a,b奇偶不同&#xff0c;c一定是奇数 2. 若b为偶数&#xff0c;c-b和cb一定是完全平方数 3. 设t>s>1,且均为奇数&#xff0c;则…

C++静态成员函数访问非静态成员的几种方法

https://www.cnblogs.com/rickyk/p/4238380.html 大家都知道C中类的成员函数默认都提供了this指针&#xff0c;在非静态成员函数中当你调用函数的时候&#xff0c;编译器都会“自动”帮你把这个this指针加到函数形参里去。当然在C灵活性下面&#xff0c;类还具备了静态成员和静…

费马大定理

当n>3时方程 xnynzn没有正整数解 结论很简洁&#xff0c;刚才看了一下证明的历史&#xff0c;我勒个去。。。。

类中的静态成员函数访问非静态成员变量

http://blog.csdn.net/u011857683/article/details/52294353 1.思路&#xff1a; 静态成员函数属于类(通过类访问&#xff0c;调用函数时没有提供this指针)&#xff0c; 非静态成员函数属于实例&#xff08;通过对象访问&#xff09;&#xff08;默认都提供了this指针&#xf…

Pollar Rho算法

原本是想把这个算法搞懂的&#xff0c;然后在网上看了又看&#xff0c;觉得&#xff0c;还是有时间再来看吧&#xff0c;我错了。 看到了一个大佬的博客&#xff0c;顺带收集一下板子 这个板子可以求大数的最大的因子。 #define LL long long bool IsPrime(LL);//返回素性测…

小知识点总结

用户输入一个url之后到整个页面返回给客户这个过程都经历了一些什么 首先url是为了让人记忆方便的,计算机在进行网络传输的过程中只能通过ip地址找到对应的主机,所以当输入一个ip地址的时候,此时就需要找对应的url,首先从浏览器中取查找ip地址,再到系统中去查找,再到域名解析服…

C++学习之普通函数指针与成员函数指针

http://blog.csdn.net/lisonglisonglisong/article/details/38353863 函数指针&#xff08;function pointer&#xff09;是通过指向函数的指针间接调用函数。相信很多人对指向一般函数的函数指针使用的比较多&#xff0c;而对指向类成员函数的函数指针则比较陌生。我最近也被问…

HDU2683——欧拉完全数

题目要求符合等式的数&#xff0c;我们首先要做的就是分析这个数&#xff1a; 对于这个等式&#xff0c;我们可能什么都看不出来&#xff0c;左边很难化简的样子&#xff0c;所以我们就要想到通过变化怎么样把右边化成和左边形式差不多的样子。结合组合数我们想到二项式定理&am…

BZOJ-2005能量采集-数论函数

很入门的数论函数题目。我还是wa了一发&#xff08;爆long long 了&#xff09; 对于每个位置x,y&#xff0c;在他们和能量采集器中间的植物为gcd(x,y)-1&#xff0c;【在他们之间说明斜率相同&#xff0c;而和他们斜率相同的就是所有gcd(x/gcd(x,y),y/gcd(x,y))1的并且比他们小…

网络五层模型

TCP/IP五层模型 应用层: HTTP,HTTPS协议,其中HTTP没有对数据进行加密操作,但是HTTPS对数据进行了加密操作 其中HTTP端口号一般是80/8080等等,HTTPS端口号是443,SSH端口号一般是22,ftp是21 HTTP协议报头: 首行:请求方法,url,协议版本 请求报头: HOST:主机 Connection:长连接…

C++的静态成员函数指针

http://blog.csdn.net/sky453589103/article/details/47276789 先简单的说说非静态的成员函数。非静态成员函数指针的类型&#xff1a;类的非静态成员是和类的对象相关的。也就是说&#xff0c;要通过类的对象来访问变量。成员函数的类型定义为&#xff1a;typedef void (A::*p…

从一个字符串中删除另一个字符串中出现过的字符

http://blog.csdn.net/walkerkalr/article/details/39001155 定义一个函数&#xff0c;输入两个字符串&#xff0c;从第一个字符串中删除在第二个中出现过的所偶字符串。例如从第一个字符串"We are students."中删除第二个字符中“auiou”中出现过的字符得到的结果是…

SPOJ-VLATTICE Visible Lattice Points-莫比乌斯反演

需要将问题分解一下。 我们需要求的是这个立方体从(0,0,0)能看到的点的个数。可是在三个含有(0,0,0)的面上我们没有办法和其他的一起进行分析&#xff08;因为含有坐标是0&#xff0c;而我们的数论工具都是从1开始的&#xff09;&#xff0c;所以我们可以将那三个面分开考虑&a…

进程的通信

管道 什么是管道 由于进程之间是相互独立的,因此在进程与进程之间进行相互联系的时候,此时就需要采用一种机制,通过管道的方式将进程一个进程的执行数据交给另外一个进程,此时就可以以通过管道来实现 匿名管道和命名管道 匿名管道 创建一个匿名管道的方式是pipe(int pipe[…

获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf

http://blog.csdn.net/windeal3203/article/details/39320605 Linux 下 可以使用ioctl()函数 以及 结构体 struct ifreq 结构体struct ifconf来获取网络接口的各种信息。 ioctl 首先看ioctl()用法ioctl()原型如下&#xff1a;#include <sys/ioctl.h>int ioctl(int fd, i…

欧拉降幂

我们记f(n)为n的欧拉函数值&#xff0c;则 当B>f©时&#xff0c;AB%CAB%f©f©%C&#xff0c;这里A,C可能不互质。 很好用&#xff0c;证明很复杂&#xff0c;等有时间回来学习一下。

房多多面试总结

测试一个ATM机 功能上 取钱     正常         要取的钱的面值是否支持ATM机服务         要取的钱的数目是否小于等于存的钱的数目         要取的钱的数目大于存钱的数目     异常         取钱的时候操作出现异常&#xff0c;导致…

BZOJ3884上帝与集合的正确用法-欧拉函数

刚开始我想的是欧拉降幂&#xff0c;可是觉得复杂度还是挺高的就去找了一下题解。 思路大方向没有问题&#xff0c;仍然是使用欧拉函数降低指数然后递归处理。但是不是简单的使用欧拉降幂而是应该对模数p稍微处理一下。因为底数已经确定为2&#xff0c;所以我们可以将p写成p2k…

比较ArrayList和数组的区别

区别1:创建时的区别 一般数组在创建的时候都需要指定数组的大小&#xff0c;但是ArrayList不需要指定数组的大小 //创建一个ArrayList对象 ArrayList<String> myList new ArrayList<String>(); //创建一个数组 String [] myList new String[2];区别2&#xff1…

linux C如何获取服务器节点上所有网口的ip地址

http://blog.csdn.net/weiyuefei/article/details/22198659 之前项目原因&#xff0c;需要获取当前服务器节点上所有网口的ip地址&#xff0c;但是当时由于时间比较紧&#xff0c;一直没搞出来&#xff0c;最近没那么忙了&#xff0c;又在网上找了一下&#xff0c;终于实现了这…