sem_wait sem_post信号量操作进本函数
sem_wait sem_post
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
sem_wait sem_post信号量操作进本函数的更多相关文章
- ZT sem_init sem_wait sem_post sem_destroy
sem_init() 2009-06-26 16:43:11| 分类: linux |字号 订阅 信号量的数据类型为结构sem_t,它本质上是一个长整型的数.函数sem_init()用来 ...
- 解密jQuery内核 DOM操作的核心函数domManip
domManip是什么 dom即Dom元素,Manip是Manipulate的缩写,连在一起就是Dom操作的意思. .domManip()是jQuery DOM操作的核心函数 对封装的节点操作做了参数 ...
- Python:常见操作字符串的函数
Python中提供了很多操作字符串的函数: string = "hello, my dear python!" string.capitalize() #将字符串中的第一个字母大写 ...
- C++调用动态库中的虚基类成员函数时总是进错函数
原创文章,转载请注明作者与本文原始URL. 问题描述:最近遇到这样一个问题,在调用C++的一个成员函数时,总是进错函数.在调用 pMsg->GetMsgContent() 的时候,总是进入到 p ...
- url_for()中的坑,url_for操作对象是函数,而不是route里的路径
url_for操作对象是函数,而不是route里的路径. url_for操作对象是函数,而不是route里的路径. url_for操作对象是函数,而不是route里的路径.
- PYDay6- 内置函数、验证码、文件操作、发送邮件函数
1.内置函数 1.1Python的内置函数 abs() dict() help() min() setattr() all() dir() hex() next() slice() any() div ...
- PHP操作文件常用函数
[获取文件信息的函数] basename($path[,扩展名]) 返回文件路径中去掉路径后的文件名称."/root/a.txt"输出a.txt;带上.txt输出a. dirnam ...
- LInux文件基础知识和文件目录操作(系统调用函数方式)
1.进程是处于活动状态的程序,某个用户通过操作系统运行程序所产生的进程代表着该用户的行为.如果用户不具备访问某个目录和文件的权限,那么该用户的进程也不能访问. 2.Linux系统中文件安全机制是通过给 ...
- 操作COOKIE的函数
一个同学慧涛分享给我的他写的操作cookie的函数,贴出来,做个笔记: //操作cookie //删除cookie hcookie('cookiename','','del'); //查询cookie ...
随机推荐
- OpenStack RPC框架解析
1 消息队列Rabbitmq介绍 Rabbitmq的整体架构图 (1)Rabbitmq Server:中间那部分就是Rabbitmq Server,也叫broken server,主要是负责消息的传 ...
- A. Vasya and Book ( Codeforces Educational Codeforces Round 55 )
题意:当前在看书的第 x 页,每次可以向前或者向后翻 d 页,这个书一共 n 页,问能否用最小操作翻到第 y 页. 题解:三种情况:1.直接翻能到的一定最短. 2.先翻到第一页,然后往后翻,翻到第 y ...
- Lombok:小辣椒的安装与使用
0.简介 Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具, 通过使用对应的注解,可以在编译源码的时候生成对应的方法,官网有详细的使用说明和视频. ...
- Spring MVC国际化配置
Spring MVC国际化配置 前言 项目开发中要考虑支持国际化,框架选用的是Spring MVC框架,那么问题来了Spring MVC如何配置并实现国际化. 实现过程(Maven项目) 对于Spri ...
- virtualBox虚拟机Ubuntu系统与主机Windows共享文件夹
1.在virtualBox虚拟机中安装Ubuntu系统 2.打开虚拟机后,安装VirtualBox增强功能包(VBoxGuestAdditions),参照下图,如果确认已经安装就直接跳过至第4步. 3 ...
- Spark(五十):使用JvisualVM监控Spark Executor JVM
引导 Windows环境下JvisulaVM一般存在于安装了JDK的目录${JAVA_HOME}/bin/JvisualVM.exe,它支持(本地和远程)jstatd和JMX两种方式连接远程JVM. ...
- Enhancer | 增强子 专题
要做就做深做精! Everything needs good justification. The interpretation should be biologically and statisti ...
- Chaos Engineering 混沌工程 Chaos Monkey vs Chaos xxx vs Chaos Blade
Chaos Engineering的历史.原则以及实践https://www.infoq.cn/article/chaos-engineering-the-history-principles-and ...
- 开源社区人们总说的LGTM是什么意思?
答: LGTM就是Looks Good To Me(已经review了,可以合并)的意思
- postgresql 查看用户名
查看当前连接的用户名: foo=#select * from current_user; 或 foo=#select user; 查看所有用户名: foo=#\du 用户管理可以查看之前的博文: ht ...