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

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;
}

http://www.xdnf.cn/news/14510.html

相关文章:

  • PHP Swoft2 框架精华系列:Config 配置解析,使用说明
  • 如何在 Elementary OS 上安装 Google Chrome 浏览器
  • 智慧流水线在ESOP数字工厂中的作用
  • 迈向通用具身智能:具身智能的综述与发展路线
  • 前端如何调用外部api获取省市区数据
  • leetcode138-随机链表的复制
  • 技术突破与落地应用:端到端 2.0 时代辅助驾驶TOP10 论文深度拆解系列【第四篇(排名不分先后)】
  • 【C++】模板入门
  • LeetCode HOT 100
  • C语言空指针异常在Java中的解决方案
  • 智慧流水线在esop数字工厂中的作用?
  • GO语言---短变量声明
  • 手写简版React-router
  • DeepSeek提示词指南:从基础到高阶的全面解析
  • 160. 相交链表
  • MGR集群场景恢复处理
  • LoRA 与传统矩阵分解的比较
  • Ubuntu24.04一键安装ROS2
  • PoE供电异常如何排查?
  • React-router 基础使用
  • Markdown 使用 mermaid 绘制图
  • 基于Webserver的数据采集
  • Redis Cluster集群机制原理
  • 安卓9.0系统修改定制化____支持安卓9.0系统修改的一些解包 打包工具解析 基础篇 三
  • TC3xx学习笔记-启动过程详解(二)
  • 最新文章 支持一下!!
  • Datawhale---AI办公实践与应用---Cpt2-用讯飞智文做一个小案例
  • 一个高质量的社交电商APP客户端UI解决方案
  • Nginx 配置中·IP地址变量
  • 深度学习的优化⽅法