当前位置: 首页 > news >正文

linux多线程之POSIX信号量

        

目录

1. 信号量的概念

2. POSIX 信号量相关函数

初始化信号量 :sem_init

获取信号量 :sem_wait

释放信号量 : sem_post

销毁信号量 :sem_destroy

3. 示例代码


POSIX 信号量是 POSIX 操作系统标准定义的一种同步原语,用于多线程(以及多进程)环境中的同步与互斥操作。在多线程编程中,POSIX 信号量有助于控制对共享资源的访问,防止竞态条件的发生。

1. 信号量的概念

        信号量本质上是一个整型变量,它通过一个计数器来控制对共享资源的访问。当线程需要访问共享资源时,它会尝试获取信号量(将计数器减 1)。如果计数器的值大于 0,获取操作成功,线程可以继续执行;如果计数器的值为 0,线程将被阻塞,直到其他线程释放信号量(将计数器加 1)。

2. POSIX 信号量相关函数

初始化信号量 :sem_init
  • 函数原型
    int sem_init(sem_t *sem, int pshared, unsigned int value);
    
  • 功能:初始化一个未命名的信号量。
  • 参数
    • sem:指向要初始化的信号量变量的指针。
    • pshared:用于指定信号量的共享方式。如果 pshared 的值为 0,表示这个信号量是当前进程内的线程共享;如果 pshared 非 0,表示这个信号量可以在多个进程间共享(常用于进程间通信场景)。在多线程场景中,通常设置为 0。
    • value:指定信号量的初始值。这个值表示可用资源的数量。例如,如果 value 为 1,通常用于实现互斥锁(因为同一时间只允许一个线程获取信号量,即只有一个线程能访问共享资源);如果 value 大于 1,则可以允许多个线程同时访问共享资源,具体数量由 value 决定。
  • 返回值:成功时返回 0,失败时返回 -1,并设置 errno 以指示错误原因,如 EINVAL(无效的参数)或 ENOMEM(内存不足)。
获取信号量 :sem_wait
  • 函数原型
    int sem_wait(sem_t *sem);
    
  • 功能:尝试获取信号量。如果信号量的值大于 0,函数将信号量的值减 1,然后返回,调用线程可以继续执行;如果信号量的值为 0,调用线程会被阻塞,直到信号量的值变为大于 0。
  • 参数sem 指向要操作的信号量变量的指针。
  • 返回值:成功时返回 0,失败时返回 -1,并设置 errno 来表示错误原因,如 EINTR(操作被信号中断)。
释放信号量 : sem_post
  • 函数原型
    int sem_post(sem_t *sem);
    
  • 功能:释放信号量,将信号量的值加 1。如果有其他线程正在等待该信号量(即信号量的值为 0 且有线程在 sem_wait 中阻塞),则会唤醒其中一个等待线程,使其能够获取信号量并继续执行。
  • 参数sem 指向要操作的信号量变量的指针。
  • 返回值:成功时返回 0,失败时返回 -1,并设置 errno 指示错误原因,如 EINVAL(无效的信号量)。
销毁信号量 :sem_destroy
  • 函数原型
    int sem_destroy(sem_t *sem);
    
  • 功能:销毁一个已初始化的信号量,释放与之相关的所有资源。在销毁信号量之前,应确保没有线程正在等待该信号量,并且所有对该信号量的操作已经完成。
  • 参数sem 指向要销毁的信号量变量的指针。
  • 返回值:成功时返回 0,失败时返回 -1,并设置 errno 指示错误原因,如 EBUSY(信号量正在被使用)。

3. 示例代码

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>// 定义共享资源和信号量
int shared_resource = 0;
sem_t semaphore;// 线程函数
void* increment_shared_resource(void* arg) {// 获取信号量sem_wait(&semaphore);shared_resource++;printf("Thread incremented shared_resource to %d\n", shared_resource);// 释放信号量sem_post(&semaphore);return NULL;
}int main() {const int num_threads = 5;pthread_t threads[num_threads];// 初始化信号量if (sem_init(&semaphore, 0, 1) != 0) {perror("Semaphore initialization failed");return 1;}// 创建线程for (int i = 0; i < num_threads; i++) {if (pthread_create(&threads[i], NULL, increment_shared_resource, NULL) != 0) {perror("Thread creation failed");return 1;}}// 等待所有线程完成for (int i = 0; i < num_threads; i++) {if (pthread_join(threads[i], NULL) != 0) {perror("Thread join failed");return 1;}}// 销毁信号量sem_destroy(&semaphore);return 0;
}

相关文章:

  • Python变量与数据类型全解析
  • AI视野:视频处理AI排行榜Top10 | 2025年05月
  • SpringJPA统计数据库表行数及更新频率
  • 37-Oracle 23 ai Shrink Tablespace(一键收缩表空间)
  • 打卡day54
  • Pico rp2040开发之Vscode插件+ c/c++独立环境搭建
  • Python中async协程快速理解
  • Vue3相关知识1
  • SHA-2
  • 安卓9.0系统修改定制化____支持安卓9.0系统修改的一些解包 打包工具解析 基础篇 三
  • 日语学习-日语知识点小记-进阶-JLPT-真题训练-N2阶段(2):2020年12月2018年7月
  • Python基础教学:小数保留位数方法总结-由Deepseek产生
  • c++类型擦除
  • 从bootloader跳到APP需要几步?
  • JavaSE: 数组详解
  • [直播推流] rtmpdump 库学习
  • 严格三角形方程组
  • Unity中的transform.Translate
  • MySQL-DCL数据控制语言详解
  • gcc升级问题
  • 百度做网站靠什么收费/最近的新闻摘抄
  • 阆中做网站/网站编辑
  • 十大免费游戏网站点开即玩/网络推广是啥
  • 网站前台展示/百度百度一下一下
  • 莱州市做网站的公司/自媒体发布平台
  • 温州网站建设设计/东莞搜索引擎推广