C 语言编程 — semaphore 信号量操作
创始人
2025-05-28 03:15:28
0

目录

文章目录

  • 目录
  • 信号量
  • 二元信号量
    • semaphore.h 库
      • sem_init()
      • sem_wait()
      • sem_post()
    • 示例程序

信号量

信号量(semaphore)是一种常被用于多线程或多进程场景中的同步机制,用于保证多线程或多进程对共享数据的读/写操作是顺序的。

信号量的本质上是一个计数器,维护着一个 Value:

  • 当 value > 0 时,信号量表示有可用的资源。
  • 当 value < 0 时,信号量表示所有的资源都已经被占用了。

二元信号量

二元信号量(Binary Semaphore),即:计数器维护的 Value 只有 0 和 1 着两种可能,以此来实现互斥,所以也称为互斥信号量。

  • 1:表示可以访问资源。
  • 0:表示不能访问资源。

需要注意的是,二元信号量只能用于实现互斥,无法实现同步。如果需要实现线程间的同步,可以使用计数信号量(Counting Semaphore)。

另外,二元信号量的使用应尽量避免死锁问题的发生,即:避免出现多个线程相互等待的情况。

semaphore.h 库

C 语言可以使用 semaphore.h 库来使用二元信号量。

sem_init()

函数作用:用于创建并初始化一个二元信号量实体。

函数原型

  • sem 参数:指向一个信号量实体。
  • pshared 参数:是一个类型标志位。
    • 0:表示信号量是在多线程间共享的;
    • non-0:表示信号量是在多进程间共享的。
  • value 参数:表示信号量的初始值,只能为 0 或 1。
#include int sem_init(sem_t *sem, int pshared, unsigned int value);

sem_wait()

函数作用

  • 如果二元信号量的 Value 为 0,那么 sem_wait() 会将 Caller(调用者)阻塞,等待 Value 变 1 为止。
  • 如果 Value 为 1,那么 sem_wait() 会将其减 1 并返回 0,表示自己拿到了信号;

函数原型

  • sem 参数:指向一个信号量实体。
#include int sem_wait(sem_t *sem);

sem_post()

函数作用:当线程完成了共享数据的访问后,应该使用 sem_post() 释放二元信号量,即:将 Value 变 1,让其他线程可以获取。

函数原型

  • sem 参数:指向一个信号量实体。
#include int sem_post(sem_t *sem);

示例程序

#include 
#include 
#include 
#include #define NUM_THREADS 2sem_t mutex;void* thread_func(void* arg) {int tid = *(int*) arg;printf("Thread %d waiting...\n", tid);/* 用一个互斥信号量来保护一个临界区。 */sem_wait(&mutex);  // 每个线程都先等待信号量变为正,然后进入临界区进行操作。printf("Thread %d entered critical section.\n", tid);sleep(1);printf("Thread %d exiting critical section.\n", tid);sem_post(&mutex);  // 离开临界区并释放信号量。pthread_exit(NULL);
}int main() {pthread_t threads[NUM_THREADS];int thread_args[NUM_THREADS];int i;// Initialize the semaphoresem_init(&mutex, 0, 1);// Create the threadsfor (i = 0; i < NUM_THREADS; i++) {thread_args[i] = i;pthread_create(&threads[i], NULL, thread_func, &thread_args[i]);}// Wait for the threads to finishfor (i = 0; i < NUM_THREADS; i++) {pthread_join(threads[i], NULL);}// Destroy the semaphoresem_destroy(&mutex);return 0;
}

相关内容

热门资讯

wxPython 之 wx.g... 前言1、派生按钮渲染器与按钮编辑器2、表格实现3、编辑调试代码:4、完整可运行代码 前...
最新或2023(历届)祖国发展... 导语:祖国在发展,在一天天强大,在一天天繁荣,在一天天富强。在日益壮大,在变的更加繁荣昌盛;我在成长...
python协程 文章目录一、前言二、介绍2.1 为什么要用协程2.2 协程的效率受到哪些限制2.3 协程的意义三、协...
第19章 随机波动率模型入门 这学期会时不时更新一下伊曼纽尔·德曼(Emanuel Derman) 教...
最新或2023(历届)关于祖国...  导语:爱国是一种高尚而朴素的民族精神,是一种无法用言语描绘的美好的东西。我将会用这种精神去描绘祖国...
最新或2023(历届)祖国发展... 导语:随着时间的变化,我们的祖国飞速发展,我们也在祖国的怀抱中健康成长。下面分享一些关于祖国发展我成...
最新或2023(历届)祖国发展... 导语:我为我的祖国不断发展壮大而自豪。祖国不断发展,我快乐成长。从现在起,我要更加努力学习,学好本领...
《世界棒球》:黑人联盟 黑人联盟(英语:Negro Leagues)(...
最新或2023(历届)伟大的长... 导语:长城是中华民族的象征,它全长一万两千多里,是世界上最伟大的建筑之一。下面分享一些关于长城的手抄...
数据库-进阶篇-10-索引 索引是一种数据结构(有序),是帮助MySQL高效获取数据的...
Recording and p... 文章目录ros2 bag 命令简介1. 准备环境2. 选择一个话题3. ros2 bag recor...
除法求值 Floyd 算法 目录除法求值Floyd 算法 除法求值 题目链接 给你一个变量对数组 equations 和一个实数...
最新或2023(历届)初中长城... 导语:下面分享一些关于长城的手抄报资料,希望对大家有所帮助!  【长城手抄报资料】  资料1:励志歌...
最新或2023(历届)关于长城... 导语:下面分享一些关于长城的手抄报资料,希望对大家有所帮助!  【长城手抄报资料】  毛泽东诗词:不...
最新或2023(历届)小学生关... 小学生关于法制手抄报的图片模板  小学生关于法制手抄报图片1  小学生关于法制手抄报图片2  小学生...
mac删除文件夹它又自动恢复 ... 我们在使用电脑的过程中,需要不断地去清理电脑中不用或废弃的文件,从而保证...
最新或2023(历届)小学生关... 小学生关于法制手抄报的图片参考  小学生关于法制手抄报参考图片(1)  小学生关于法制手抄报参考图片...
最新或2023(历届)简单的法... 简单的法制手抄报的图片模板  简单的法制手抄报图片1  简单的法制手抄报图片2  简单的法制手抄报图...
图形视图框架QGraphics... QGraphicsView(图形视图) QGraphicsView提供了...
大数据学习(2) 大数据学习(2)0 数据仓库0.0 数据仓库基本概念0.1 数据仓库主要...