线程并发执行带来的问题

  线程并发会引发一些难以发现的错误,现在就来看一个简单的线程的并发导致的问题,首先来看下面程序,程序很简单,就是创建了3个线程,第一个线程对i和count加1,第二个线程对j和count加1,第三个线程对k和count加1,i,j,k,count初始化都为0,这样的华,按照逻辑来说,最后i+j+k = count:

 

 
  
1 #include < stdio.h >
2 #include < stdlib.h >
3 #include < pthread.h >
4
5   int count = 0 ;
6   int i = 0 ;
7   int j = 0 ;
8   int k = 0 ;
9
10   /* 给i的值和count的值加1 */
11 void * modify_i_thread( void * data)
12 {
13 for (;;) {
14 i ++ ;
15 count ++ ;
16 }
17 }
18
19 /* 给j的值和count的值加1 */
20 void * modify_j_thread( void * data)
21 {
22 for (;;) {
23 j ++ ;
24 count ++ ;
25 }
26 }
27
28 /* 给k的值和count的值加1 */
29 void * modify_k_thread( void * data)
30 {
31 for (;;) {
32 k ++ ;
33 count ++ ;
34 }
35 }
36
37 int main( void )
38 {
39 pthread_t pthid;
40
41 /* 创建三个线程 */
42 pthread_create( & pthid, NULL, modify_i_thread, NULL);
43 pthread_create( & pthid, NULL, modify_j_thread, NULL);
44 pthread_create( & pthid, NULL, modify_k_thread, NULL);
45
46 sleep( 1 );
47
48 /* 打印结果 */
49 printf( " i = %d, j = %d, k= %d, count = %d\n " , i, j, k, count);
50 printf( " i+j+k=%d\n " , i + j + k);
51
52 return 0 ;
53 }

 

在我机子上执行的结果是:

i = 92394160, j = 55544601, k= 42663454, count = 74003307
i+j+k=190606856

 

  很明显,i+j+k != count,为什么会发生这样的问题呢?首先我们可以肯定的是,按照数学逻辑上讲,本文一开始的假定(i+j+k = count)是正确的,但是执行结果却出乎我们的意料,或许,问题就出在线程的并发执行上。再来仔细分析下创建的线程执行的操作,3个线程中都对count进行了++操作,++操作在C语言中看起来是一条语句,实际上编译后是3条语句,首先将count的值写入寄存器,然后对其进行加1操作,在接着将寄存器的值读出,保存在count中。现在来再看看这个程序,三个线程简称为A、B、C,如果A刚刚把count的值写入寄存器中,此时调度程序调度B线程开始运行,这个时候,B对count进行了N次加法操作,此时count = count+N,此时调度程序恢复执行A线程,那么此时A中保存的count的值却是是B线程执行前的值,此时,A再对count进行操作时,就是基于旧的值(其他线程对count进行操作前的值),而不是最新的值,所以count的值并不是我们期望中的值。

  一个小小的并发程序,却也引出了这样的一个问题,所以在遇到并发程序时,最好先想想怎么样利用同步和互斥操作来避免这样的错误。错误之处,还轻您斧正。先谢谢啦。

转载于:https://www.cnblogs.com/huangwei/archive/2010/05/25/1743938.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值