当前位置:首页 > 嵌入式 > 嵌入式软件

本文将说明如何使用信号量实现线程之间的互斥与同步。互斥锁只有0,1两中状态,适合于线程对共享资源的独占访问,很多时候每个资源可以同时被有限的线程访问,此时互斥锁将无法满足;条件变量同步也同样存在这种问题。信号量实际是一种非负整型计数器,可以很好的控制线程之间资源访问,互斥锁能实现的功能,信号量同样可以。

信号量控制资源共享主要是PV原语操作, PV原语是对整数计数器信号量sem的操作。一次 P操作使 sem减一,而一次 V操作使sem 加一。进程(或线程)根据信号量的值来判断是否对公共资源具有访问权限。当信号量sem 的值大于等于零时,该进程(或线程)具有公共资源的访问权限;相反,当信号量 sem的值小于零时,该进程(或线程)就将阻塞直到信号量 sem的值大于等于 0 为止。

Linux 实现了POSIX 的无名信号量,主要用于线程间的互斥同步。这里主要介绍几个常见函数。
· sem_init用于创建一个信号量,并能初始化它的值。
· sem_wait和sem_trywait相当于P操作,它们都能将信号量的值减一,两者的区别在 于若信号量小于零时,sem_wait将会阻塞进程,而 sem_trywait则会立即返回。
· sem_post相当于V操作,它将信号量的值加一同时发出信号唤醒等待的进程。
· sem_getvalue用于得到信号量的值。
· sem_destroy用于删除信号量。
所需头文件 #i nclude

函数原型 int sem_init(sem_t *sem,int pshared,unsigned int value)
sem:信号量
pshared:决定信号量能否在几个进程间共享。由于目前Linux还没有实现进程间共享信号量,所以这个值只能够取0
value:信号量初始化值
函数返回值 成功:0 ,出错:-1

所需头文件 #i nclude
函数原型
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:信号量
函数返回值 成功:0 ,出错:-1

从上面函数来看,实现线程之间同步信号量比互斥锁使用起来相对容易一些,操作简单,容易理解,适用范围广。

下面上一篇的问题用信号量来实现,线程使用部分没变,主要改变了对资源的控制方式:(代码本人亲自编译通过)

view plaincopy to clipboardprint?
01.#i nclude
02.#i nclude
03.#i nclude
04.#i nclude
05.#i nclude
06.#i nclude
07.
08.int g_Flag = 0;
09.sem_t sem_mutex; // 用于互斥
10.sem_t sem_syn; // 用于同步
11.
12.void *thread1( void *arg );
13.void *thread2( void *arg );
14.int main()
15.{
16. pthread_t tid1, tid2;
17. int rc1, rc2;
18.
19. sem_init( &sem_mutex, 0, 1 );
20. sem_init( &sem_syn, 0, 0 );
21. printf( " Inter main !n" );
22.
23. rc2 = pthread_create( &tid2, NULL, thread2, NULL );
24. if( rc2 != 0 )
25. printf( " %s, %d n", __func__, strerror( rc2 ) );
26.
27. rc1 = pthread_create( &tid1, NULL, thread1, &tid2 );
28. if( rc1 != 0 )
29. printf( " %s, %d n", __func__, strerror(rc1) );
30. printf( " Leave main!nn" );
31.
32. sem_wait( &sem_syn ); // 同步等待,阻塞
33. exit( 0 );
34.}
35.
36.void *thread1( void *arg )
37.{
38. pthread_t *ptid = NULL;
39. printf( " Enter thread1n" );
40. printf( " thread1 id: %u, g_Flag: %d n", ( unsigned int )pthread_self(), g_Flag );
41.
42. if( sem_wait( &sem_mutex ) != 0)
43. {
44. perror(" pthread1 sem_mutexn");
45. }
46.
47. if( g_Flag == 2 )
48. sem_post( &sem_syn );
49. g_Flag = 1;
50.
51. if( sem_post( &sem_mutex ) != 0)
52. {
53. perror( "pthread1 sem_postn" );
54. }
55. printf( " thread1 id: %u, g_Flag: %d n",( unsigned int )pthread_self(), g_Flag );
56. printf( "Leave thread1 nn" );
57.
58. ptid = ( pthread_t *)arg;
59. printf( " ptid = %u n", *ptid );
60. pthread_join( *ptid, NULL );
61. pthread_exit(0 );
62.}
63.
64.void *thread2( void *arg )
65.{
66. printf( " Enter thread2 !n" );
67. printf( " thread2 id: %u , g_Flag: %d n", ( unsigned int)pthread_self(), g_Flag );
68.
69. if( sem_wait( &sem_mutex ) != 0 )
70. {
71. perror( "thread2 sem_wait n" );
72. }
73.
74. if( g_Flag == 1 )
75. sem_post( &sem_syn );
76.
77. g_Flag = 2;
78.
79. if( sem_post( &sem_mutex ) != 0)
80. {
81. perror( " thread2 sem_postn" );
82. }
83. printf( " thread2 id: %u , g_Flag: %d n", ( unsigned int )pthread_self(), g_Flag );
84. printf( "Leave thread2 nn" );
85.
86. pthread_exit(0);
87.}



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭