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 ...
随机推荐
- 记一次清理缓存的小事情(chrome) chrome下清理缓存不生效的问题
记一次清理缓存的小事情(chrome) chrome下清理缓存不生效的问题 前端开发中会经常涉及清理缓存的事情. 在一次开发后, 需要清理缓存,一个哥们怎么清理都不生效, 于是向我求救. 在我看了下后 ...
- [DOM] Input elements should have autocomplete attributes (suggested: autocomplete='tel', confirm at
译文概要:输入元素应该有自动完成的属性,比如: autocomplete=’tel’. autocomplete 用途: 此功能主要是记住输入内容,下次提交表单或者浏览器回退后,还能保持表单内容不变. ...
- Python 的特性
Copyright © 1999-2019, CSDN.NET, All Rights Reserved 原 python面试题整理(一) 崔先生的博客阅读数:2402018-08-03 前言 ...
- webbench 源代码
WebBench源码:https://github.com/EZLippi/WebBench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问 ...
- vue中全局filter和局部filter怎么用?
需求: 将价值上加上元单位符号(全局filter) <template> <div> 衣服价格:{{productPrice|formatTime}} </div> ...
- 为 Raft 引入 leader lease 机制解决集群脑裂时的 stale read 问题
问题:当 raft group 发生脑裂的情况下,老的 raft leader 可能在一段时间内并不知道新的 leader 已经被选举出来,这时候客户端在老的 leader 上可能会读取出陈旧的数据( ...
- MySql的动态语句foreach各种用法比较
1.单参数List的类型: 上述collection的值为list,对应的Mapper是这样的 2.单参数array数组的类型: 上述collection为array,对应的Mapper代码: 3.自 ...
- [Windows] 输入字符间距变宽
今天在输入时,不会到误触到哪里,输入的字符间距变得很宽,如下图: 最后找到原因是不小心同时按下了 Shift+Space(空格),进入全角模式,就会导致输入的字符间距变宽 想要恢复,再按一次 shif ...
- #C++初学记录(判断子串#数学结合)
A Count Task Problem Description Count is one of WNJXYK's favorite tasks. Recently, he had a very lo ...
- SQL学习笔记(二)
连接查询 数据准备 例1:查询学生信息及学生的成绩 等值连接 此方法会产生笛卡尔积,生成的记录总数=表1的总数*表2的总数,会产生临时表 内连接 select * from 表1 inner join ...