c语言pthreadcond条件变量,线程同步之条件变量

一.概述:

条件变量是线程同步的一种机制,它是通过一个条件,当条件满足时,唤醒一个线程,但条件不满足时,挂起该线程。由于同步是伴随着互斥的,所以条件变量一般都伴随着互斥锁。

二.相关函数:

(1).cond:pthread_cond_t  cond  =  PTHREAD_COND_INITIALIZER

cond是一个全局变量,和mutex一样。

(2).pthread_cond_init函数:int  pthread_cond_init(pthread_cond_t  *restrict  cond,

const  pthread_condattr_t  *restrict  attr)

attr参数:用于初始化cond,NULL表示缺省属性。weiNULL时和声明一个全局的cond一样。

返回值:成功返回0,失败返回错误号。

PS:restrict,C语言中的一种类型限定符(TypeQualifiers),用于告诉编译器,对象已经被指针所引用,不能通过除该指针外所有其他直接或间接的方式修改该对象的内容。

(3).phtread_cond_destroy函数:int  pthread_cond_destroy(pthread_cond_t *cond)

函数功能:销毁cond。

返回值:成功返回0,失败返回错误号。

(4).pthread_cond_timedwait函数:int  pthread_cond_timedwait(pthread_cond_t *restrict  cond,

pthread_mutex_t *restrict  mutex,

const  struct timespaec *restrict abstime)

函数功能:将当前线程挂起,直到有信号将其唤醒或出现错误返回。

sbstime参数:等待超时时间,如果到达了abstime所指定的 时刻仍然没有别的线程来唤醒当前线程,就返回ETIMEDOUT。

返回值:成功返回0,失败返回错误号。

(5).pthread_cond_wait函数:int  pthread_cond_timedwait(pthread_cond_t *restrict  cond,

pthread_mutex_t *restrict  mutex)

函数功能:将当前线程挂起,直到有信号将其唤醒或出现错误返回。

返回值:成功返回0,失败返回错误号。

(6).pthread_cond_signal函数:int pthread_cond_signal(pthread_cond_t *cond)

函数功能:发出一个信号给用cond等待挂起的线程,使之进入就绪态。

返回值:成功返回0,失败返回错误号。

(7).pthread_cond_broadcastsignal函数:int pthread_cond_signal(pthread_cond_t *cond)

函数功能:发出一个信号给所有用cond等待挂起的线程,使它们都进入就绪态。

返回值:成功返回0,失败返回错误号。

三.相关代码:(生产者与消费者模型)(必须是生产者先生产,消费者再消费的顺序)

在没有加互斥锁和条件变量之前:1 #include

2 #include

3 #include

4 #include

5

6 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

7 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

8

9 typedef struct node

10 {

11     int _data;

12     struct node* _next;

13 }node_t, *node_p, **node_pp;

14

15 node_p head = NULL;

16 int g_data;                   //用于表示消费的数据

17

18 node_p buy_node(int data)

19 {

20     node_p tem = malloc(sizeof(node_t));

21     if(tem)

22     {

23         tem->_data = data;

24         tem->_next = NULL;

25         return tem;

26     }

27     return NULL;

28 }

29

30

31 void init_list(node_pp list)

32 {

33     *list = buy_node(0);

34 }

35

36 void head_push(node_p list, int data)

37 {

38     node_p tem = buy_node(data);

39     tem->_next = list->_next;

40     list->_next = tem;

41 }

42

43 int tail_pop(node_p list)

44 {

45     if(list->_next == NULL)

46     {

47         g_data = -1;

48         return -1;

49     }

50

51     node_p tem = list;

52     node_p del = NULL;

53     while(tem->_next != NULL)

54     {

55         del = tem->_next;

56         if(tem->_next->_next == NULL)

57         {

58             tem->_next = NULL;

59         }

60         else

61         {

62             tem = tem->_next;

63         }

64     }

65

66     g_data = del->_data;

67     free(del);

68     return 0;

69 }

70

71 void show_list(node_p list)

72 {

73     node_p tem = list;

74     while(tem != NULL)

75     {

76         printf("%d  ",tem->_data);

77         tem = tem->_next;

78     }

79     printf("\n");

80 }

81

82 void* product(void* ptr)

83 {

84     int i = 1;

85     while(1)

86     {

87         head_push(head, i);

88         sleep(1);

89         printf("product data -> %d\n",i);

90         i++;

91     }

92 }

93

94 void* consumer(void* ptr)

95 {

96     while(1)

97     {

98         tail_pop(head);

99         sleep(1);

100         printf("consumer data -> %d\n", g_data);

101     }

102 }

103

104

105

106

107 int main()

108 {

109     init_list(&head);

110

111

112     pthread_t tid1, tid2;

113     pthread_create(&tid1, NULL, product, NULL);

114     pthread_create(&tid2,NULL, consumer, NULL);

115     pthread_join(tid1, NULL);

116     pthread_join(tid2, NULL);

117

118     pthread_mutex_destroy(&lock);

119     pthread_cond_destroy(&cond);

120

121

122 //  int i = 1;

123 //  while(i <= 5)

124 //  {

125 //      head_push(head, i++);

126 //      show_list(head);

127 //  }

128 //  printf("-------------------------------------\n");

129 //  while(i >= 1)

130 //  {

131 //      tail_pop(head);

132 //      show_list(head);

133 //      i--;

134 //  }

135

136     return 0;

137 }

138

139

140

执行结果:

89e7d1704a3916d59cadec81f33059d3.png

PS:可以看到结果为消费者先消费,而不是生产者先生产。

用互斥锁和条件变量:1 #include

2 #include

3 #include

4 #include

5

6 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

7 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

8

9 typedef struct node

10 {

11     int _data;

12     struct node* _next;

13 }node_t, *node_p, **node_pp;

14

15 node_p head = NULL;            //头指针

16 int g_data;                   //用于表示消费的数据

17

18 node_p buy_node(int data)

19 {

20     node_p tem = malloc(sizeof(node_t));

21

if(tem)

22     {

23         tem->_data = data;

24         tem->_next = NULL;

25         return tem;

26     }

27     return NULL;

28 }

29

30

31 void init_list(node_pp list)

32 {

33     *list = buy_node(0);

34 }

35

36 void head_push(node_p list, int data)

37 {

38     node_p tem = buy_node(data);

39     tem->_next = list->_next;

40     list->_next = tem;

41 }

42

43 int tail_pop(node_p list)

44 {

45     if(list->_next == NULL)

46

{

47         g_data = -1;

48         return -1;

49     }

50

51     node_p tem = list;

52     node_p del = NULL;

53     while(tem->_next != NULL)

54     {

55         del = tem->_next;

56         if(tem->_next->_next == NULL)

57         {

58             tem->_next = NULL;

59         }

60         else

61         {

62             tem = tem->_next;

63         }

64     }

65

66     g_data = del->_data;

67     free(del);

68     return 0;

69 }

70

71 void show_list(node_p list)

72 {

73     node_p tem = list;

74     while(tem != NULL)

75     {

76         printf("%d  ",tem->_data);

77         tem = tem->_next;

78     }

79     printf("\n");

80 }

81

82 void* product(void* ptr)

83 {

84     int i = 1;

85     while(1)

86     {

87         pthread_mutex_lock(&lock);

88         head_push(head, i);

89         sleep(1);

90         i++;

91         pthread_mutex_unlock(&lock);

92         printf("product data -> %d\n",i);

93         pthread_cond_signal(&cond);     //生产一个就可以唤醒消费者了

94     }

95 }

96

97 void* consumer(void* ptr)

98 {

99     while(1)

100     {

101         pthread_mutex_lock(&lock);

102         while(head->_next == NULL)      //注意要用while为不是if  因为可能会出现一个错误信号把

103         {                               //该线程唤醒,但链表内并没有数据的可能。

104             pthread_cond_wait(&cond, &lock);

105         }

106         tail_pop(head);

107         sleep(1);

108         pthread_mutex_unlock(&lock);

109         printf("consumer data -> %d\n", g_data);

110     }

111 }

112

113

114 int main()

115 {

116     init_list(&head);

117

118

119     pthread_t tid1, tid2;

120     pthread_create(&tid1, NULL, product, NULL);

121     pthread_create(&tid2,NULL, consumer, NULL);

122     pthread_join(tid1, NULL);

123     pthread_join(tid2, NULL);

124

125     pthread_mutex_destroy(&lock);

126     pthread_cond_destroy(&cond);

127

128

129//  int i = 1;

130 //  while(i <= 5)

131 //  {

132 //      head_push(head, i++);

133 //      show_list(head);

134 //  }

135 //  printf("-------------------------------------\n");

136 //  while(i >= 1)

137 //  {

138 //      tail_pop(head);

139 //      show_list(head);

140 //      i--;

141 //  }

142

143     return 0;

144 }

145

146

147

147,0-1      底端

129,1         82%

执行结果:

f1add673e6c0dacc845e0114140ea86b.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值