首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

能帮忙看下这段代码为什么会出现这种结果吗? 关于线程的,该怎么处理

2012-02-29 
能帮忙看下这段代码为什么会出现这种结果吗? 关于线程的代码很简单,启动两个线程,一个对全局变量all加1(用

能帮忙看下这段代码为什么会出现这种结果吗? 关于线程的
代码很简单,启动两个线程,一个对全局变量all加1(用for循环操作360次),另一个减1

但是运行结果却很奇怪,好像每个线程会拥有一个all的拷贝一样,对all操作是对这个拷贝操作,而不是对全局变量操作

C/C++ code
#include <stdio.h>#include <string.h>#include <windows.h>#define NOPV 1int demo(int argc, char *argv[]);volatile int all = 0;long allsingal = 1;int p(long &singal){    #ifdef NOPV        return 1;    #endif    printf("p\n");    while(singal <= 0)    {        Sleep(1);    }    singal--;    return 0;}int v(long &singal){    #ifdef NOPV        return 1;    #endif    printf("v\n");    singal++;    return 0;}DWORD __stdcall threadadd(LPVOID pfin){    int *finshed = (int *)pfin;    int tmp;    for (int i = 0; i < 360; i++)    {    //        p(allsingal);        tmp = ::all;        printf("add all = %d\n", all);        Sleep(10);        ::all = tmp + 1;//        v(allsingal);    }    *finshed = 1;    return 0;}DWORD __stdcall threaddec(LPVOID pfin){    int *finshed = (int *)pfin;    int tmp;    for (int i = 0; i < 360; i++)    {//        p(allsingal);        tmp = ::all;        printf("dec all = %d\n", all);        Sleep(10);        ::all = tmp - 1;//        v(allsingal);    }    *finshed = 1;    return 0;}int main(int argc, char *argv[]){    printf("%d\n" ,argc);    DWORD nID1;    DWORD nID2;    int EndT1 = 0;    int EndT2 = 0;    CreateThread(NULL, 0, threadadd, &EndT1, 0, &nID1);    CreateThread(NULL, 0, threaddec, &EndT2, 0, &nID2);    while(!(EndT1 & EndT2))    {        printf("all = %d\n", all);        Sleep(10);    }    printf("all = %d\n", all);    return 0;}

部分结果如下:

all = -260
add all = 261
dec all = -261
all = -261
add all = 262
dec all = -262
all = -262
add all = 263
dec all = -263
all = -263
add all = 264
dec all = -264
all = -264
add all = 265
dec all = -265
all = -265
add all = 266
dec all = -266
all = -266
add all = 267
dec all = -267
all = -267
add all = 268
dec all = -268
all = -268
add all = 269
dec all = -269
all = -269
add all = 270
dec all = -270
all = -270
add all = 271
dec all = -271
all = -271
add all = 272
dec all = -272
all = -272
add all = 273
dec all = -273
all = -273
add all = 274

看得出,线程1总是对一个正的拷贝进行操作
而线程2总是对一个负的拷贝进行操作

[解决办法]
不用volatile修饰得变量,在载入寄存器以后,优化算法是不再去重新载入他,因此看起来会象私有拷贝。
[解决办法]
问题就在 Sleep 的次序上。Sleep会挂起当前的线程,并执行下一个等候的线程。
由于两个线程都有一个 temp 保存 all 的值,这样,大体上的执行过程是这样的:
threadadd:
add.temp = all;
output;
sleep;
threaddec:
dec.temp = all;
output;
sleep;
threadadd:
all = add.temp + 1;
next loop:
add.temp = all;
output;
sleep;
threaddec:
all = dec.temp - 1;
next loop:
dec.temp = all;
output;
sleep;
threadadd:
......
如此循环。
可以看出,输出的值实际上依赖于 temp,而不是 all。
你可以试着把Sleep放到循环的最后,效果应该和放到循环的最前面是一样的。

热点排行