Linux下线程间同步-信号量 原创 Linux平台 2022年4月2日 16:12 夏至未至 832 当前内容 2915 字,在路上,马上到,马上到 ### 目录 [TOC] ### 何为信号量 信号灯(semaphore),也叫信号量。它是不同进程间或一个给定进程内部不同线程间同步的机制。信号灯包括posix有名信号灯、 posix基于内存的信号灯(无名信号灯)和System V信号灯(IPC对象)。信号量广泛用于进程或线程间的同步和互斥,信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问,编程时可根据操作信号量值的结果判断是否对公共资源具有访问权限,当信号量值大于0时,则可以访问,否则将阻塞。PV原语是对信号量的操作,一次P操作使信号量减1,一次V操作使信号量加1。 ### 信号量使用 #### 方法介绍 1>初始化 #include int sem_init(sem_t *sem,int pshared,unsigned int value); 功能:创建一个信号量并初始化它的值,一个无名信号量在被使用前必须初始化 参数:sem 信号量地址 pshared 等于0 信号量在线程间共享 不等于0 信号在进程间共享 value 信号量的初始值 返回:成功 0 失败 -1 2>销毁 #include int sem_destroy(sem_t *sem); 功能 删除sem标识的信号量 参数 sem 信号量地址 返回 成功 0 失败 -1 3>P操作(减1) #include int sem_wait(sem_t *sem); 功能 将信号量的值减1,操作前,先检查信号量(sem)的值是否为0,若为0,则阻塞,直到信号量大于0再减 参数 sem 信号量地址 返回 成功 0 失败 -1 4>非阻塞减1 int sem_trywait(sem_t *sem); 以非阻塞的方式来对信号量进行减1操作,若操作前,信号量的值等于0,则对信号量的操作失败,函数立即返回 5>限时减1 int sem_timedwait(sem_t *sem,const struct timespec *abs_timeout); 限时尝试将信号量的值减1,abs_timeout 绝对时间。 6>V操作(加1) #include int sem_post(sem_t *sem); 功能 将信号量的值加1,并发出信号唤醒等待线程(sem_wait()); 参数 sem 信号量地址 返回 成功 0 失败 -1 7>获取信号量的值 #include int sem_getvalue(sem_t *sem,int *val); 功能 获取sem标识的信号量的值,保存在val中 参数 sem 信号量地址 val 保存信号量值的地址 返回 成功 0 失败 -1 #### 代码举例 场景:通过信号量模拟2个窗口,10个客人进行服务的过程,信号量的值代表空闲的服务窗口,每个窗口一次只能服务一个人,有空闲窗口,开始服务前,信号量-1,服务完成后信号量+1 #include #include #include #include #include #include #include #include using namespace std; // 客户人数 int customerNumber = 10; // 信号量 sem_t serviceSem; // 客户得到服务 void *GetService(void *userId) { int customerId = *((int*)userId); if (sem_wait(&serviceSem) == 0) { // 信号量减一成功,说明之前是大于1的,减一之后就是0了,其他线程进不来了 sleep(5); cout << "customer " << customerId << " get the service" << endl; cout << "customer " << customerId << " done " << endl; // 待本客户处理完成业务,信号量加1,其他客户就又可以得到服务了 sem_post(&serviceSem); } return 0; } int main() { // 初始化信号量 sem_init(&serviceSem, 0, 2); pthread_t customer[customerNumber]; int result = -1; for (int i = 0; i < customerNumber; i++) { int customerId = i; result = pthread_create(&customer[i], NULL, GetService, &customerId); if (result) { cout << "pthread create error" << endl; return result; } else { cout << "customer " << i << " arrived " << endl; } sleep(1); } // 等待所有线程结束,即所有客户都得到了服务 for (int j = 0; j < customerNumber; j++) { pthread_join(customer[j], NULL); } // 销毁信号量 sem_destroy(&serviceSem); return 0; } 本文标题: Linux下线程间同步-信号量 本文作者: 夏至未至 发布时间: 2022年4月2日 16:12 最近更新: 2022年4月2日 16:12 原文链接: 许可协议: 署名-非商业性-禁止演绎 4.0 国际(CC BY-NC-ND 4.0) 请按协议转载并保留原文链接及作者 线程间同步(5) 上一个 PyCharm安装与永久激活 下一个 Linux下线程间同步-读写锁 当前文章评论暂未开放,请移步至留言处留言。