sem_wait sem_post信号量操作进本函数

2023-05-16

sem_wait   sem_post

信号量的数据类型为结构sem_t,它本质上是一个长整型的数。函数sem_init()用来初始化一个信号量。它的原型为:  

extern int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value));  

sem为指向信号量结构的一个指针;pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;value给出了信号量的初始值。  

函数sem_post( sem_t *sem )用来增加信号量的值。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。  

函数sem_wait( sem_t *sem )被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。函数sem_trywait ( sem_t *sem )是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。  

函数sem_destroy(sem_t *sem)用来释放信号量sem。 

信号量用sem_init函数创建的,下面是它的说明:
  #include<semaphore.h>
 int sem_init (sem_t *sem, int pshared, unsigned int value);

 这个函数的作用是对由sem指定的信号量进行初始化,设置好它的共享选项,并指定一个整数类型的初始值。pshared参数控制着信号量的类型。如果 pshared的值是0,就表示它是当前里程的局部信号量;否则,其它进程就能够共享这个信号量。我们现在只对不让进程共享的信号量感兴趣。 (这个参数受版本影响), pshared传递一个非零将会使函数调用失败。

  这两个函数控制着信号量的值,它们的定义如下所示:

#include <semaphore.h>
 int sem_wait(sem_t * sem);
 int sem_post(sem_t * sem);
  这两个函数都要用一个由sem_init调用初始化的信号量对象的指针做参数。
  sem_post函数的作用是给信号量的值加上一个“1”,它是一个“原子操作”---即同时对同一个信号量做加“1”操作的两个线程是不会冲突的;而同时对同一个文件进行读、加和写操作的两个程序就有可能会引起冲突。信号量的值永远会正确地加一个“2”--因为有两个线程试图改变它。
  sem_wait函数也是一个原子操作,它的作用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法。也就是说,如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,介信号量的值将减到1。如果对一个值为0的信号量调用sem_wait(),这个函数就会地等待直到有其它线程增加了这个值使它不再是0为止。如果有两个线程都在sem_wait()中等待同一个信号量变成非零值,那么当它被第三个线程增加一个“1”时,等待线程中只有一个能够对信号量做减法并继续执行,另一个还将处于等待状态。
  信号量这种“只用一个函数就能原子化地测试和设置”的能力下正是它的价值所在。还有另外一个信号量函数sem_trywait,它是sem_wait的非阻塞搭档。

  最后一个信号量函数是sem_destroy。这个函数的作用是在我们用完信号量对它进行清理。下面的定义:
  #include<semaphore.h>
  int sem_destroy (sem_t *sem);
  这个函数也使用一个信号量指针做参数,归还自己战胜的一切资源。在清理信号量的时候如果还有线程在等待它,用户就会收到一个错误。
  与其它的函数一样,这些函数在成功时都返回“0”。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>

sem_t bin_sem;
void *thread_function1(void *arg)
{
printf("thread_function1--------------sem_wait\n");
sem_wait(&bin_sem);
printf("sem_wait\n");
while (1)
{
}
}

void *thread_function2(void *arg)
{
printf("thread_function2--------------sem_post\n");
sem_post(&bin_sem);
printf("sem_post\n");
while (1)
{
}
}



int main()
{
int res;
pthread_t a_thread;
void *thread_result;

res = sem_init(&bin_sem, 0, 0);
if (res != 0)
{
 perror("Semaphore initialization failed");
}
 printf("sem_init\n");
res = pthread_create(&a_thread, NULL, thread_function1, NULL);
if (res != 0)
{
 perror("Thread creation failure");
}
printf("thread_function1\n");
sleep (5);
printf("sleep\n");
res = pthread_create(&a_thread, NULL, thread_function2, NULL);
if (res != 0)
{
 perror("Thread creation failure");
}
while (1)
{
}
}


sem_init
thread_function1
thread_function1--------------sem_wait
sleep
thread_function2--------------sem_post
sem_wait
sem_post

来自:  http://hi.baidu.com/lsdyst/blog/item/527c4d91aa8bb280a877a471.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

sem_wait sem_post信号量操作进本函数 的相关文章

随机推荐

  • 【性能优化】cpu时间抖动问题的解决修复

    问题描述 xff1a 边缘设备的cpu在低占有率时 xff0c 进程运行时间抖动较大 xff0c 在高占有率时 xff0c 运行时间抖动更稳定 低占有率运行情况图 xff1a 相同处理逻辑循环中 xff0c 两次处理的时间间隔 xff1a
  • pointRCNN 结果可视化

    由于pointRCNN源码的训练和inference很详细 xff0c 但是没有可视化的代码 xff0c 本文介绍其3d框结果的可视化方法 1 跑通pointRCNN https github com sshaoshuai PointRCN
  • C/C++学习笔记——C提高: 函数指针和递归函数

    函数指针 函数类型 通过什么来区分两个不同的函数 xff1f 一个函数在编译时被分配一个入口地址 xff0c 这个地址就称为函数的指针 xff0c 函数名代表函数的入口地址 函数三要素 xff1a 名称 参数 返回值 C语言中的函数有自己特
  • 算法基础22-最小生成树

    最小生成树 primkruskal prim 链接 acwing上一个关于prim很好的题解 prim 算法干的事情是 xff1a 给定一个无向图 xff0c 在图中选择若干条边把图的所有节点连起来 要求边长之和最小 在图论中 xff0c
  • C/C++学习笔记——C提高:预处理

    预处理的基本概念 C语言对源程序处理的四个步骤 xff1a 预处理 编译 汇编 链接 预处理是在程序源代码被编译之前 xff0c 由预处理器 xff08 Preprocessor xff09 对程序源代码进行的处理 这个过程并不对程序的源代
  • C/C++学习笔记——C提高:动态库的封装和使用

    库的基本概念 库是已经写好的 成熟的 可复用的代码 每个程序都需要依赖很多底层库 xff0c 不可能每个人的代码从零开始编写代码 xff0c 因此库的存在具有非常重要的意义 在我们的开发的应用中经常有一些公共代码是需要反复使用的 xff0c
  • FreeRTOS学习笔记——基础知识与移植(STM32F103)

    1 1 前后台系统 xff1a 早期嵌入式开发没有嵌入式操作系统的概念 xff0c 直接操作裸机 xff0c 在裸机上写程序 xff0c 比如用51单片机基本就没有操作系统的概念 通常把程序分为两部分 xff1a 前台系统和后台系统 简单的
  • STM32开源代码——MAX30100程序

    正点原子精英开发板 模块化封装 xff0c 入口函数简明 xff0c 易上手操作 展示main c代码 xff0c 完整代码请下载 xff08 数据打印到串口在MAX30100 PulseOximeter c xff09 点击下载代码 in
  • STM32开源代码——2.8寸TFTLCD屏虚拟键盘触摸程序

    正点原子精英开发板 模块化封装 xff0c 入口函数简明 xff0c 易上手操作 展示main c代码 xff0c 完整代码请下载 点击下载代码 include 34 sys h 34 include 34 delay h 34 inclu
  • STM32开源代码——光敏传感器

    正点原子精英开发板 模块化封装 xff0c 入口函数简明 xff0c 易上手操作 展示main c代码 xff0c 完整代码请下载 点击下载代码 include 34 led h 34 include 34 delay h 34 inclu
  • 个人项目——机智云开源APP基础修改教程(Android)

    之前写过一篇STM32接入机智云的教程 xff0c 最后说要有时间给大家写一篇修改机智云开源Demo APP的教程 xff0c 刚好楼主考完直流传动 xff0c 然后帮小学弟的一个32项目接入了机智云 xff0c 然后打算帮他修改一下Dem
  • FreeRTOS学习笔记——FreeRTOS任务创建和删除实验(静态方法)

    6 3 任务创建和删除实验 静态方法 6 3 1 实验程序设计 1 实验目的 上一小节我们讲了使用函数xTaskCreate 来创建任务 xff0c 本节在上一小节的基础上做简单的修改 xff0c 使用函数xTaskCreateStatic
  • FreeRTOS学习笔记——FreeRTOS 系统内核控制函数

    FreeRTOS 中有一些函数只供系统内核使用 xff0c 用户应用程序一般不允许使用 xff0c 这些API 函数就是系统内核控制函数 本章我们就来学习一下这些内核控制函数 xff0c 本章分为如下几部分 xff1a 10 1 内核控制函
  • FreeRTOS学习笔记——FreeRTOS 时间管理

    在使用FreeRTOS 的过程中我们通常会在一个任务函数中使用延时函数对这个任务延时 xff0c 当执行延时函数的时候就会进行任务切换 xff0c 并且此任务就会进入阻塞态 xff0c 直到延时完成 xff0c 任务重新进入就绪态 延时函数
  • 算法基础23-二分图

    二分图 二分图的判断二分图的最大匹配数 可以去看acwing题解 二分图的判断 span class token comment AcWing 860 染色法判定二分图 span span class token macro propert
  • Router 选择

    Connected Dominating Set Example of a Connected Dominating Set Router 必须形成一个 CDS xff08 Connected Dominating Set xff0c 连接
  • devtool: unset _PYTHON_SYSCONFIGDATA_NAME

    问题 在 Ubuntu 20 04 1 LTS 上进行编译Yocto时报错 xff0c 出现如下错误 xff1a bb data smart ExpansionError Failure expanding variable SRCPV e
  • VsCode 配置PySide6及测试

    目录 VSCode插件安装安装Python插件安装PySide6插件 PySide6安装PySide6配置VSCode创建UI文件 在这里插入图片描述 https img blog csdnimg cn cbf7cd76d7d84048ab
  • Ubuntu 14.04 Desktop的Raid1安装总结

    Ubuntu 14 04 Desktop的Raid1安装总结 安装基于Ubuntu14 04 Desktop的Raid1 由于采用UEFI GPT方式作为系统启动方式 xff0c 在安装过程中出现了很多异常情况 本文记录安装的过程 安装步骤
  • sem_wait sem_post信号量操作进本函数

    sem wait sem post 信号量的数据类型为结构sem t xff0c 它本质上是一个长整型的数 函数sem init xff08 xff09 用来初始化一个信号量 它的原型为 xff1a extern int sem init