首页
社区
课程
招聘
[讨论]Event编程疑惑 || 爱国版XP与正版XP之讨论
发表于: 2008-2-20 20:30 7005

[讨论]Event编程疑惑 || 爱国版XP与正版XP之讨论

2008-2-20 20:30
7005
写在前面:
整个寒假都在学习VC++,孙鑫的那本书终于看结束了了,
几乎每一个实例都跟着一起做了一遍,同时之际还加以扩展一下。
自己很开心,首先在这里庆贺一下


好了,直接说正题把。

孙鑫的书里面有一个Event实例如下:(线程同步的一个例子)


#include <windows.h>
#include <iostream.h>

DWORD WINAPI myThreadProc1(LPVOID lpParameter);
DWORD WINAPI myThreadProc2(LPVOID lpParameter);

int g_tickets = 100;
HANDLE g_hEvent;

CRITICAL_SECTION cs;

void main()
{
//创建两个买票线程
HANDLE hThread1 = CreateThread(NULL,0,myThreadProc1,NULL,0,NULL);
HANDLE hThread2 = CreateThread(NULL,0,myThreadProc2,NULL,0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);

//创建自动重置的事件对象
g_hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
/*g_hEvent = CreateEvent(NULL,FALSE,FALSE,"tickets sale");
if(g_hEvent)
{
if(ERROR_ALREADY_EXISTS == GetLastError())
{
cout<<"Only one instance can run!"<<endl;
return;
}
}
*/
SetEvent(g_hEvent);//开始卖票
Sleep(4000);
CloseHandle(g_hEvent);
}

DWORD WINAPI myThreadProc1(LPVOID lpParameter)
{
while(TRUE)
{
WaitForSingleObject(g_hEvent,INFINITE);
if(g_tickets>0)
{
Sleep(1);
cout<<"Thread 1 selled ticket "<<g_tickets--<<endl;
}
else
{
SetEvent(g_hEvent);
break;
}
SetEvent(g_hEvent);
}
return 0;
}

DWORD WINAPI myThreadProc2(LPVOID lpParameter)
{
while(TRUE)
{
WaitForSingleObject(g_hEvent,INFINITE);
if(g_tickets>0)
{
Sleep(1);
cout<<"Thread 2 selled ticket "<<g_tickets--<<endl;
}
else
{
SetEvent(g_hEvent);
break;
}
SetEvent(g_hEvent);
}
return 0;
}


我还是自信这段代码没有太大问题的。

但是运行结果却有点让人不满意。
理想的情况是这样的:

但是偶尔会出现这样的情况:

显然线程同步出现问题。
然而,
第二天我重新启动机器,运行结果出奇良好:连续100次没有一次出错。
而今天,有三番五次的出现这种问题。


我所使用的XP是爱国版的, ,所以我怀疑是因为爱国版的XP内核不稳的问题。

但是还是希望各位看客能够看出代码中的问题,给予指正。
小弟VC++入门尚浅,但是一是勤奋,二是谦虚,在这两个方面我还是有很不错的表现的。

希望大家讨论讨论。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (16)
雪    币: 247
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
2
自己顶一个!!!
大家都说说看法把
2008-2-20 20:55
0
雪    币: 1946
活跃值: (243)
能力值: (RANK:330 )
在线值:
发帖
回帖
粉丝
3
我还是自信这段代码没有太大问题的。

g_tickets--
加个临界
2008-2-20 21:11
0
雪    币: 247
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
4
[QUOTE=Bughoho;418528]我还是自信这段代码没有太大问题的。

g_tickets--
加个临界[/QUOTE]

看样子我的XP确实性能不稳了
2008-2-20 21:21
0
雪    币: 1946
活跃值: (243)
能力值: (RANK:330 )
在线值:
发帖
回帖
粉丝
5
看来你没明白我的意思 你的是代码问题 什么爱国版 恨国版 上海版 fuck god。
2008-2-20 21:25
0
雪    币: 255
活跃值: (207)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
6
我所使用的XP是爱国版的.

难道爱国版是重写了内核,注入了中国民族血液?
2008-2-20 21:32
0
雪    币: 247
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
7
我看有可能!!!

注:其实我以前用的是正版的,但是正版这事那事太多嫌麻烦。重装了
2008-2-20 21:34
0
雪    币: 247
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
8
我是使用事件对象同步的,和临界区同步没有什么区别啊
2008-2-20 21:37
0
雪    币: 247
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
9
昨天晚上想了一宿。。。
决定用其他人的机器测试一下。

发觉他们的结果没有错误——甚至包括寝室里面最慢最慢的笨驴子!
我还用我的电脑上的VMware测试了一下,也没有出错

所以感慨一下——我要重装系统了——我的系统真的有问题了,(我怀疑是驱动问题)

昨晚迅雷不停出错,可能也是线程同步问题,

(D版系统确实不太稳定,被我瞎整一通,问题大大)

欢迎大家也发表一下看法吧。
2008-2-21 08:24
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
10
g_tickets作为全局变量在多线程中使用,
不能直接操作,需要用原子操作来访问
g_tickets--经过编译器后可能生成3个汇编指令
可以使用InterlockedExchangeAdd来实现原子访问操作
2008-2-21 18:51
0
雪    币: 247
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
11
各位的指教我先收下了。。
我得好好研究一下Event,CriticalSection,Semaphore,atomic addition,Mutext,的关系和区别
2008-2-22 09:19
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
代码看上去是确实没什么问题。。。
2008-2-22 11:48
0
雪    币: 234
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
13
很好奇
真的有这么多种版啊
不知可有好事者创见个仙人版版呢
呵呵
2008-2-25 06:42
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
呵呵,仙人版?我们家乡就有种食品就叫做“仙人粄”的,广州这边都叫“凉粉”
2008-2-26 21:13
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
据说微软推荐用  临界区
HOHO。。
2008-2-26 23:31
0
雪    币: 234
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
16
仁兄你说的很有趣啊

“仙人粄”不曾听过
“凉粉”这就知道也甲过
呵呵
2008-2-28 03:40
0
雪    币: 8599
活跃值: (5060)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
17
#include <windows.h>
#include <iostream.h>

DWORD WINAPI myThreadProc1(LPVOID lpParameter);
DWORD WINAPI myThreadProc2(LPVOID lpParameter);

int g_tickets = 100;
HANDLE g_hEvent;

CRITICAL_SECTION cs;

void main()
{
        InitializeCriticalSection(&cs);
        //创建两个买票线程
        HANDLE hThread1 = CreateThread(NULL,0,myThreadProc1,NULL,0,NULL);
        HANDLE hThread2 = CreateThread(NULL,0,myThreadProc2,NULL,0,NULL);
        CloseHandle(hThread1);
        CloseHandle(hThread2);

       
       
        //创建自动重置的事件对象
        g_hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
        /*g_hEvent = CreateEvent(NULL,FALSE,FALSE,"tickets sale");
        if(g_hEvent)
        {
    if(ERROR_ALREADY_EXISTS == GetLastError())
    {
        cout<<"Only one instance can run!"<<endl;
        return;
    }
        }
        */
        SetEvent(g_hEvent);//开始卖票
        Sleep(4000);
        CloseHandle(g_hEvent);
        //DeleteCriticalSection(&cs);
        system("pause");
}

DWORD WINAPI myThreadProc1(LPVOID lpParameter)
{
        while(TRUE)
        {
                WaitForSingleObject(g_hEvent,INFINITE);
                if(g_tickets>0)
                {
                        EnterCriticalSection(&cs);
                        Sleep(1);
                        cout<<"Thread 1 selled ticket "<<g_tickets--<<endl;
                        LeaveCriticalSection(&cs);
                }
                else
                {
                        SetEvent(g_hEvent);
                        break;
                }
                SetEvent(g_hEvent);
        }
        return 0;
}

DWORD WINAPI myThreadProc2(LPVOID lpParameter)
{
        while(TRUE)
        {
                WaitForSingleObject(g_hEvent,INFINITE);
                if(g_tickets>0)
                {
                        EnterCriticalSection(&cs);
                        Sleep(1);
                        cout<<"Thread 2 selled ticket "<<g_tickets--<<endl;
                        LeaveCriticalSection(&cs);
                }
                else
                {
                        SetEvent(g_hEvent);
                        break;
                }
                SetEvent(g_hEvent);
        }
        return 0;
}
2008-2-29 11:05
0
游客
登录 | 注册 方可回帖
返回
//