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传递一个非零将会使函数调用失败。

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

  1. #include <semaphore.h>
  2. int sem_wait(sem_t * sem);
  3. 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”。

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <pthread.h>
  6. #include <semaphore.h>
  7. sem_t bin_sem;
  8. void *thread_function1(void *arg)
  9. {
  10. printf("thread_function1--------------sem_wait\n");
  11. sem_wait(&bin_sem);
  12. printf("sem_wait\n");
  13. while (1)
  14. {
  15. }
  16. }
  17. void *thread_function2(void *arg)
  18. {
  19. printf("thread_function2--------------sem_post\n");
  20. sem_post(&bin_sem);
  21. printf("sem_post\n");
  22. while (1)
  23. {
  24. }
  25. }
  26. int main()
  27. {
  28. int res;
  29. pthread_t a_thread;
  30. void *thread_result;
  31. res = sem_init(&bin_sem, 0, 0);
  32. if (res != 0)
  33. {
  34. perror("Semaphore initialization failed");
  35. }
  36. printf("sem_init\n");
  37. res = pthread_create(&a_thread, NULL, thread_function1, NULL);
  38. if (res != 0)
  39. {
  40. perror("Thread creation failure");
  41. }
  42. printf("thread_function1\n");
  43. sleep (5);
  44. printf("sleep\n");
  45. res = pthread_create(&a_thread, NULL, thread_function2, NULL);
  46. if (res != 0)
  47. {
  48. perror("Thread creation failure");
  49. }
  50. while (1)
  51. {
  52. }
  53. }
  54. sem_init
  55. thread_function1
  56. thread_function1--------------sem_wait
  57. sleep
  58. thread_function2--------------sem_post
  59. sem_wait
  60. sem_post

转自:sem_wait sem_post信号量操作进本函数

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

  1. ZT sem_init sem_wait sem_post sem_destroy

    sem_init() 2009-06-26 16:43:11|  分类: linux |字号 订阅       信号量的数据类型为结构sem_t,它本质上是一个长整型的数.函数sem_init()用来 ...

  2. 解密jQuery内核 DOM操作的核心函数domManip

    domManip是什么 dom即Dom元素,Manip是Manipulate的缩写,连在一起就是Dom操作的意思. .domManip()是jQuery DOM操作的核心函数 对封装的节点操作做了参数 ...

  3. Python:常见操作字符串的函数

    Python中提供了很多操作字符串的函数: string = "hello, my dear python!" string.capitalize() #将字符串中的第一个字母大写 ...

  4. C++调用动态库中的虚基类成员函数时总是进错函数

    原创文章,转载请注明作者与本文原始URL. 问题描述:最近遇到这样一个问题,在调用C++的一个成员函数时,总是进错函数.在调用 pMsg->GetMsgContent() 的时候,总是进入到 p ...

  5. url_for()中的坑,url_for操作对象是函数,而不是route里的路径

    url_for操作对象是函数,而不是route里的路径. url_for操作对象是函数,而不是route里的路径. url_for操作对象是函数,而不是route里的路径.

  6. PYDay6- 内置函数、验证码、文件操作、发送邮件函数

    1.内置函数 1.1Python的内置函数 abs() dict() help() min() setattr() all() dir() hex() next() slice() any() div ...

  7. PHP操作文件常用函数

    [获取文件信息的函数] basename($path[,扩展名]) 返回文件路径中去掉路径后的文件名称."/root/a.txt"输出a.txt;带上.txt输出a. dirnam ...

  8. LInux文件基础知识和文件目录操作(系统调用函数方式)

    1.进程是处于活动状态的程序,某个用户通过操作系统运行程序所产生的进程代表着该用户的行为.如果用户不具备访问某个目录和文件的权限,那么该用户的进程也不能访问. 2.Linux系统中文件安全机制是通过给 ...

  9. 操作COOKIE的函数

    一个同学慧涛分享给我的他写的操作cookie的函数,贴出来,做个笔记: //操作cookie //删除cookie hcookie('cookiename','','del'); //查询cookie ...

随机推荐

  1. 记一次清理缓存的小事情(chrome) chrome下清理缓存不生效的问题

    记一次清理缓存的小事情(chrome) chrome下清理缓存不生效的问题 前端开发中会经常涉及清理缓存的事情. 在一次开发后, 需要清理缓存,一个哥们怎么清理都不生效, 于是向我求救. 在我看了下后 ...

  2. [DOM] Input elements should have autocomplete attributes (suggested: autocomplete='tel', confirm at

    译文概要:输入元素应该有自动完成的属性,比如: autocomplete=’tel’. autocomplete 用途: 此功能主要是记住输入内容,下次提交表单或者浏览器回退后,还能保持表单内容不变. ...

  3. Python 的特性

    Copyright © 1999-2019, CSDN.NET, All Rights Reserved     原 python面试题整理(一) 崔先生的博客阅读数:2402018-08-03 前言 ...

  4. webbench 源代码

    WebBench源码:https://github.com/EZLippi/WebBench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问 ...

  5. vue中全局filter和局部filter怎么用?

    需求: 将价值上加上元单位符号(全局filter) <template> <div> 衣服价格:{{productPrice|formatTime}} </div> ...

  6. 为 Raft 引入 leader lease 机制解决集群脑裂时的 stale read 问题

    问题:当 raft group 发生脑裂的情况下,老的 raft leader 可能在一段时间内并不知道新的 leader 已经被选举出来,这时候客户端在老的 leader 上可能会读取出陈旧的数据( ...

  7. MySql的动态语句foreach各种用法比较

    1.单参数List的类型: 上述collection的值为list,对应的Mapper是这样的 2.单参数array数组的类型: 上述collection为array,对应的Mapper代码: 3.自 ...

  8. [Windows] 输入字符间距变宽

    今天在输入时,不会到误触到哪里,输入的字符间距变得很宽,如下图: 最后找到原因是不小心同时按下了 Shift+Space(空格),进入全角模式,就会导致输入的字符间距变宽 想要恢复,再按一次 shif ...

  9. #C++初学记录(判断子串#数学结合)

    A Count Task Problem Description Count is one of WNJXYK's favorite tasks. Recently, he had a very lo ...

  10. SQL学习笔记(二)

    连接查询 数据准备 例1:查询学生信息及学生的成绩 等值连接 此方法会产生笛卡尔积,生成的记录总数=表1的总数*表2的总数,会产生临时表 内连接 select * from 表1 inner join ...