这一篇练习信号量的应用

信号量本质上是一个非负的整数计数器,也是UNIX中古老的实现进程互斥和同步的手段,Linux下信号量概念是在线程中,信号则在进程控制中,不过原理差不多,最基本最经典的操作莫过于P、V操作了,能实现进程、线程的互斥和同步操作,非常值得深入理解。

1.P、V操作原语

P操作:

proceduce P(var s:semaphore)

{

begin

s:=s-1;

if(s<0)then W(s);

end

}

V操作:

proceduce V(var s:semaphore)

{

begin

s:=s+1;

if(s<=0)then R(s);

end

}

2.基本操作

数据类型:信号量的数据类型为结构sem_t,它本质上是一个长整型的数。

函数:

(1)sem_init

功能:         用于创建一个信号量,并初始化信号量的值。

头文件:       <semaphore.h>

函数原型:     int sem_init (sem_t* sem, int pshared, unsigned int value);

函数传入值:   sem:信号量。

pshared:决定信号量能否在几个进程间共享。由于目前LINUX还没有实现进

程间共享信息量,所以这个值只能取0。

value:初始计算器

函数返回值:   0:成功。

-1:失败。

(2)其他函数。

//等待信号量

int sem_wait       (sem_t* sem);

int sem_trywait   (sem_t* sem);

//发送信号量

int sem_post       (sem_t* sem);

//得到信号量值

int sem_getvalue (sem_t* sem);

//删除信号量

int sem_destroy   (sem_t* sem);

功能:sem_wait和sem_trywait相当于P操作,它们都能将信号量的值减一,两者的区别在

于若信号量的值小于零时,sem_wait将会阻塞进程,而sem_trywait则会立即返回。

sem_post相当于V操作,它将信号量的值加一,同时发出唤醒的信号给等待的进程

(或线程)。

sem_getvalue 得到信号量的值。

sem_destroy 摧毁信号量。

函数传入值: sem:信号量。

函数返回值: 同上。

好了,了解完基本操作,继续做一个练习:

这里用信号量实现互斥资源访问的功能:

  1. /*sem.c*/
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <pthread.h>
  5. #include <semaphore.h>
  6. #include <errno.h>
  7. /*全局变量*/
  8. int gnum = 0;
  9. /*信号量*/
  10. sem_t sem;
  11. /*声明线程运行服务程序*/
  12. static void pthread_func_1 (void);
  13. static void pthread_func_2 (void);
  14. int main (void)
  15. {
  16. /*线程的标识符*/
  17. pthread_t pt_1 = 0;
  18. pthread_t pt_2 = 0;
  19. int ret = 0;
  20. /*信号量初始化*/
  21. sem_init(&sem,0,1);
  22. /*分别创建线程1、2*/
  23. ret = pthread_create (&pt_1,          //线程标识符指针
  24. NULL,          //默认属性
  25. (void *)pthread_func_1,//运行函数
  26. NULL);          //无参数
  27. if (ret != 0)
  28. {
  29. perror ("pthread_1_create");
  30. }
  31. ret = pthread_create (&pt_2,          //线程标识符指针
  32. NULL,           //默认属性
  33. (void *)pthread_func_2, //运行函数
  34. NULL);          //无参数
  35. if (ret != 0)
  36. {
  37. perror ("pthread_2_create");
  38. }
  39. /*等待线程1、2的结束*/
  40. pthread_join (pt_1, NULL);
  41. pthread_join (pt_2, NULL);
  42. printf ("main programme exit!/n");
  43. return 0;
  44. }
  45. /*线程1的服务程序*/
  46. static void pthread_func_1 (void)
  47. {
  48. int i = 0;
  49. for (;;)
  50. {
  51. printf ("This is pthread1!/n");
  52. sem_wait(&sem);     /*等待信号量*/
  53. sleep (1);
  54. /*临界资源*/
  55. gnum++;
  56. printf ("Thread1 add one to num:%d/n",gnum);
  57. sem_post (&sem);        /*释放信号量*/
  58. }
  59. }
  60. /*线程2的服务程序*/
  61. static void pthread_func_2 (void)
  62. {
  63. int i = 0;
  64. for (;;)
  65. {
  66. printf ("This is pthread2!/n");
  67. sem_wait(&sem);     /*等待信号量*/
  68. sleep (1);
  69. /*临界资源*/
  70. gnum++;
  71. printf ("Thread2 add one to num:%d/n",gnum);
  72. sem_post (&sem);        /*释放信号量*/
  73. }
  74. pthread_exit (0);
  75. }

编译,运行,可以看出和上次互斥锁结果一样的

Linux编程练习 --多线程5--信号量(semaphore)相关推荐

  1. Linux编程练习 --多线程3--mutex

    互斥指互相排斥的锁,是一种信号量,常用来防止两个进程或线程在同一时刻访问相同的共享资源 1.数据类型: 在Linux下, 线程的互斥量数据类型是pthread_mutex_t,我们定义一个互斥数据可以 ...

  2. Linux编程练习 --多线程2--属性的设置

    在上一篇的练习里,我们用pthread_create函数创建了一个线程,在这个线程中,我们使用了默认参数,即将该函数的第二个参数设为NULL.的确,对大多数程序来说,使用默认属性就够了,但我们还是有必 ...

  3. Linux编程练习 --多线程1--线程创建

    POSIX线程-轻量级进程,线程调度是由内核调度程序完成的,线程所消耗的系统资源比较少,相互通讯也比较容易. 多线程的优点: 1.资源消耗量少.我们知道,在Linux系统下,启动一个新的进程必须分配给 ...

  4. Linux编程练习 --多线程4--条件变量

    上一篇练习了互斥锁的用法和原理,这次学习和互斥锁一起应用的cond--条件变量 1.互斥锁的存在问题: 互斥锁一个明显的缺点是它只有两种状态:锁定和非锁定.设想一种简单情景:多个线程访问同一个共享资源 ...

  5. linux带有超时等待的信号量,C++多线程同步之Semaphore(信号量)

    一.线程间同步的几种方式 从上篇博文中可以发现,当多个线程对同一资源进行使用时,会产生"争夺"的情况,为了避免这种情况的产生,也就出现了线程间的同步这个技术.线程间的同步有多种方式 ...

  6. python并发编程之semaphore(信号量)_python并发编程之多线程

    多线程 线程 1.什么是线程 进程是一个执行空间 , 线程就是其中真正工作的单位 , 每一个进程至少有一个线程(如果我们把操作系统比喻为一个工厂 , 进程就是车间 , 线程就是流水线) 进程包含了运行 ...

  7. Linux下的多线程编程

    1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的Unix也支持线程的概念,但是在一个进程(process ...

  8. linux多线程拷贝信号量运用于线程之间通讯遇到的printf问题

    linux多线程拷贝信号量运用于线程之间通讯遇到的printf问题 1.题目内容 使用多线程实现文件的拷贝,并使用进度条进行相应的显示 2.进度 以下代码实现了多线程完成文件的拷贝,但是在使用进度条实 ...

  9. Linux编程题:信号量同步三进程依次打印若干次ABC

    三个进程依次打印ABC..... 思路及大致流程如下: 思路取自这位大哥: Linux编程题:创建3个线程分别打印abc,用信号量进行同步_cleverlemon的博客-CSDN博客 这位大哥写的是线 ...

最新文章

  1. 左右两个下拉列表框的选项互移及获值效果
  2. js取对象属性需注意
  3. Python模块学习 ---- re正则表达式
  4. how is SAP ui5 shell view implemented
  5. 编写程序,使用一维数组,模拟栈数据结构。 要求: 1、这个栈可以存储java中的任何引用类型的数据。 2、在栈中提供push方法模拟压栈。(栈满了,要有
  6. spring boot之security
  7. Skip level 1 on 1
  8. 横向滑动页面,导航条滑动居中的 js 实现思路
  9. 免费版本的mysql与收费版本的区别
  10. DNS域名解析配置详解
  11. Kali使用beef
  12. iPhone 计算机 桌面,变身iOS?让Windows 10的桌面和苹果一样美
  13. rpg服务器无限刷金币bug,荆棘谷惊现无限刷金BUG 无脑跑商盆满钵满
  14. BigDecimal运算和比较大小
  15. 阿里云ACP认证适合什么样的人考?
  16. 转载一篇--干烧失恋鲫鱼
  17. 数据结c语言约瑟夫环实验报告,数据结构约瑟夫环实验报告.doc
  18. K7的PLL使用问题
  19. 力扣春季编程大赛(LCCUP‘21)
  20. window系统中将c文件编译成so共享库

热门文章

  1. html不支持元素video,Html5中的Video元素使用方法
  2. 微服务架构与组件总览
  3. mysql安装im,mysql安装记录
  4. ribbon, restTemplate 负载均衡服务调用
  5. mybatis-plus 使用乐观锁修改
  6. 现代软件工程讲义 3 代码规范与代码复审
  7. 山东科技大学计算机等级,关于2019年03月全国计算机等级考试报名工作的通知
  8. javagei图片设置热点_【物理考点】重磅押题: 2020高考物理必考热点+命题预测+例题解析, 快快快收藏!...
  9. 重写、重构、重载区别
  10. 阿旺wifi智能系统源码