ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

多线程使用信号量sem_init,sem_wait,sem_post。转载

2022-07-15 09:02:29  阅读:132  来源: 互联网

标签:thread int void 信号量 线程 sem 多线程


首先你得知道什么叫信号量,什么时候要用信号量。
这个嘛,主要就是用来保护共享资源的,也就是说如果你想限制某个(些)资源在同一时刻只能有一(多)个线程拥有,就可以使用信号量。当然也可以用作让一个线程等待另一个线程完成某项工作。

 

 

信号量的主要函数有:

int sem_init(sem_t *sem,int pshared,unsigned int value);  //pshared是用来表示这个信号量的值是多少。一般信号量用于多个线程间共享时,这个值为0
int sem_wait(sem_t *sem);      --------如果有,获取信号量,并减1
int sem_post(sem_t *sem);      --------给信号量加1,让其他线程可启动
常用的就是上面三个,还有三个不常用的:
int sem_getvalue(sem_t *sem); -------就是读取当前的信号灯的数目
int sem_destroy(sem_t *sem); --------信号量用完后摧毁这个信号量,不再使用
int sem_trywait(sem_t *sem); ------就是测试一下看看现在有没有可用的信号灯,而不会阻塞。

可能大部分公司在使用的时候会在上面进行再次封装下。
sem_init用于对指定信号初始化,pshared为0,表示信号在当前进程的多个线程之间共享,value表示初始化信号的值。
sem_wait可以用来阻塞当前线程,直到信号量的值大于0,解除阻塞。解除阻塞后,sem的值-1,表示公共资源被执行减少了。例如:如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,信号量的值将-1。当初始化value=0后,使用sem_wai会阻塞这个线程,这个线程函数就会等待其它线程函数调用sem_post增加了了这个值使它不再是0,才开始执行,然后value值-1。 
sem_post用于增加信号量的值+1,当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制由线程的调度策略决定。

看一个例子,比如有两个线程都要往打印机上打东西,但是同一时刻只能打一个。
那么首先用sem_init初始化一个信号量,注意pshared表示允许几个进程共享该信号量,一般设0用于进程内的多线程共享,要看是否支持进程共享,请查看下你的系统的man手册。
第三个参数value表示可用的资源的数目,即信号灯的数目,咱们这儿只有1个打印机所以设成1。
然后线程调用sem_wait取获取这个信号灯,第一个线程一看,有1个,他就拿到了,然后可以继续后继操作,此时信号灯自动减1,变成0个。那么第二个线程调用sem_wait时就会阻塞在这儿了。
第一个线程完成打印后,调用sem_post释放信号灯,信号灯数目变成1,将会唤醒等待的第二个线程,然后第二个线程接着打印。
最后当所有任务完成后,主线程调用sem_destroy释放这个信号量。


下面是例程:
#include <stdio.h>
  #include <semaphore.h>

  sem_t sem;
  void* func1(void)
  {
      sem_wait(&sem);
      int *running=arg;
      printf("thread running1\n");
      printf("%d\n",*running);
  }

  void* func2(void* arg)
  {
      printf("pthread2 running\n");
      sem_post(&sem);
  }
  int main()
  {
      sem_init(&sem,0,0);
      pthread_t thread[2];
      int a=5;
      pthread_create(&(thread[0]),NULL,(void*)func,(void*)&a);
      printf("main thread running\n");
      sleep(10);
      pthread_create(&(thread[1]),NULL,(void*)func2,(void*)&a);
      printf("main thread running2\n");
      pthread_join(thread[0],NULL);
      pthread_join(thread[1],NULL);
      sem_destory(&sem);
  }

运行结果为: 
func1被阻塞,直到fun2把信号量+1,才开始执行。

main pthread running
main pthread running2
pthread2 running
pthread1 running
5

转载:
https://www.cnblogs.com/lidabo/p/8568551.html
https://blog.csdn.net/lh2016rocky/article/details/70800958

标签:thread,int,void,信号量,线程,sem,多线程
来源: https://www.cnblogs.com/beilou310/p/16480066.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有