Linux线程的信号量同步
来源:互联网
时间:2026-02-26 18:23:19
作者:
系统大全为您提供
信号量和互斥锁(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 ...", customer_id); sem_post(&sem); } } #define CUSTOMER_NUM 10 int 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.", 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 ...
以上就是系统大全给大家介绍的如何使的方法都有一定的了解了吧,好了,如果大家还想了解更多的资讯,那就赶紧点击系统大全官网吧。
本文来自系统大全https://www.herecours.com/d/file/efpub/2026/26-26/20260226180925569752
编辑推荐:
- Linux线程的信号量同步02-26
- Linux下execl学习02-26
- Linux下ApachePHPMysql默认安装路径02-26
- Linux内核开机保留大块内存的方法总结02-26
- 几个用来了解Linux系统的性能概况的Linux命令02-26
- Linux下使用Samba服务器举例02-26
- 你应该知道的16个Linux服务器监控命令(1)02-26
- Linux进程的理解02-26
下一篇:
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- Linux下使用Samba服务器举例
Linux下使用Samba服务器举例
26-02-26 - 你应该知道的16个Linux服务器监控命令(1)
你应该知道的16个Linux服务器监控命令(1)
26-02-26 - Linux中断处理流程
Linux中断处理流程
26-02-26 - Linux下Java、Maven、Tomcat的安装
Linux下Java、Maven、Tomcat的安装
26-02-26 - linux下安装jdktomcat并配置
linux下安装jdktomcat并配置
26-02-26 - Linux命令(2):ls命令
Linux命令(2):ls命令
26-02-26 - linux之虚拟机三种联网模式与远程登录管理
linux之虚拟机三种联网模式与远程登录管理
26-02-26 - Linux怎么样扩展XFS系统文件
Linux怎么样扩展XFS系统文件
26-02-26 - Linux解决文件删除了但磁盘可利用率没变
Linux解决文件删除了但磁盘可利用率没变
26-02-26 - 为Linux手动制作U盘启动及基本原理
为Linux手动制作U盘启动及基本原理
26-02-26
