快捷搜索:  as  2018  FtCWSyGV  С˵  test  xxx  Ψһ  w3viyKQx

和记娱乐最新版本app:Linux下多线程编程的互斥与同步是怎么回事



本文将阐明若何应用旌旗灯号量实现线程之间的互斥与同步。互斥只有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_和记娱乐最新版本appt *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和记娱乐最新版本app. 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 )和记娱乐最新版本app

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( &s和记娱乐最新版本appem_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( “ threa和记娱乐最新版本appd2 id: %u , g_Flag: %d n”, ( unsigned int )pthread_self(), g_Flag );

84. printf( “Leave thread2 nn” );

85.

86. pthread_exit(0);

87.}

责任编辑:ct

您可能还会对下面的文章感兴趣: