C,C ++不同步线程返回一个奇怪的结果 [英] C , C++ unsynchronized threads returning a strange result

查看:125
本文介绍了C,C ++不同步线程返回一个奇怪的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我有这个问题在一个关于线程。

有同时运行,并使用全球资源INT NUM两非同步线程
1日:

 无效线程()
{
    INT I;
    对于(i = 0; I<亿;我++)
    {
        NUM ++;
        num--;
    }
}

2日:

 无效线程2()
{
    诠释J;
    为(J = 0; J<亿; J ++)
    {
        NUM ++;
        num--;
    }
}

问题指出:什么是变量民在节目结束的可能值。
现在我要说的0将num的值在节目的最后,但尝试和运行这个code和你会发现,其结果是相当随机的,
我不明白为什么?

满code:

 的#include<&WINDOWS.H GT;
    #包括LT&;&process.h GT;
    #包括LT&;&stdio.h中GT;    INT静态NUM = 0;   无效线程()
    {
        INT I;
        对于(i = 0; I<亿;我++)
        {
            NUM ++;
            num--;
        }
    }   作废线程2()
    {
        诠释J;
        为(J = 0; J<亿; J ++)
        {
            NUM ++;
            num--;
        }
    }    诠释的main()
    {
        长手柄,handle2,code,code2;
        处理= _beginthread(螺纹,0,NULL);
        handle2 = _beginthread(线程2,0,NULL);        而((GetExit codeThread(手柄,和放大器; code)|| GetExit codeThread(handle2,&安培;!code2))= 0);        TerminateThread(手柄,code);
        TerminateThread(handle2,code2);        的printf(%D,NUM);
        系统(暂停);
    }


解决方案

NUM ++ NUM - 别吨有是原子操作。采取 NUM ++ 为例,这大概是等来实现:

  INT TMP = NUM​​;
TMP = TMP + 1;
NUM = tmp目录;

其中, TMP 在CPU寄存器举行。

现在让我们说, NUM == 0 ,两个线程试图执行 NUM ++ 和操作交错如下:

 线程A线程B
INT TMP = NUM​​;
TMP = TMP + 1;
                INT TMP = NUM​​;
                TMP = TMP + 1;
NUM = tmp目录;
                NUM = tmp目录;

在最后的结果将是 NUM == 1 即使它应该已增加两倍。在这里,一个增量丢失;以同样的方式,递减可能丢失以及

在病理情况下,一个线程的所有增量可能丢失,从而导致 NUM == -100000000 ,或一个线程的所有递减可能丢失,从而导致在 NUM ==亿。甚至有可能出现更极端的情况下潜伏在那里。

还有还有其他业务的事情,因为 NUM 不挥发声明。因此,这两个线程将假定 NUM 的值不会改变,除非他们是一个改变它。这允许编译器优化掉整个循环,若觉得这样的倾向!

Okay, i have this question in one regarding threads.

there are two unsynchronized threads running simultaneously and using a global resource "int num" 1st:

    void Thread()
{ 
    int i;
    for ( i=0 ; i < 100000000; i++ )
    {
        num++;
        num--;
    }
}

2nd:

    void Thread2()
{ 
    int j;
    for ( j=0 ; j < 100000000; j++ )
    {
        num++;
        num--;      
    }
}

The question states: what are the possible values of the variable "num" at the end of the program. now i would say 0 will be the value of num at the end of the program but, try and run this code and you will find out that the result is quite random, and i can't understand why?

The full code:

 #include <windows.h>
    #include <process.h>
    #include <stdio.h>

    int static num=0;

   void Thread()
    { 
        int i;
        for ( i=0 ; i < 100000000; i++ )
        {
            num++;
            num--;
        }
    }

   void Thread2()
    { 
        int j;
        for ( j=0 ; j < 100000000; j++ )
        {
            num++;
            num--;      
        }
    }

    int main()
    {
        long handle,handle2,code,code2;
        handle=_beginthread( Thread, 0, NULL );
        handle2=_beginthread( Thread2, 0, NULL );

        while( (GetExitCodeThread(handle,&code)||GetExitCodeThread(handle2,&code2))!=0 );

        TerminateThread(handle, code );
        TerminateThread(handle2, code2 );

        printf("%d ",num);
        system("pause"); 
    }

解决方案

num++ and num-- don't have to be atomic operations. To take num++ as an example, this is probably implemented like:

int tmp = num;
tmp = tmp + 1;
num = tmp;

where tmp is held in a CPU register.

Now let's say that num == 0, both threads try to execute num++, and the operations are interleaved as follows:

Thread A        Thread B
int tmp = num;
tmp = tmp + 1;
                int tmp = num;
                tmp = tmp + 1;
num = tmp;
                num = tmp;

The result at the end will be num == 1 even though it should have been incremented twice. Here, one increment is lost; in the same way, a decrement could be lost as well.

In pathological cases, all increments of one thread could be lost, resulting in num == -100000000, or all decrements of one thread could be lost, resulting in num == +100000000. There may even be more extreme scenarios lurking out there.

Then there's also other business going on, because num isn't declared as volatile. Both threads will therefore assume that the value of num doesn't change, unless they are the one changing it. This allows the compiler to optimize away the entire for loop, if it feels so inclined!

这篇关于C,C ++不同步线程返回一个奇怪的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆