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

线程间的通信有关问题

2012-03-12 
线程间的通信问题现在有如下的程序做到线程间的通信,在单核cpu上运行结果正确可在双核cpu上运行结果会出错

线程间的通信问题
现在有如下的程序做到线程间的通信,在单核cpu上运行结果正确

可在双核cpu上运行结果会出错,这是怎么回事?     请高手指点一下

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

DWORD   WINAPI   Fun1Proc(
    LPVOID   lpParameter       //   thread   data
);
DWORD   WINAPI   Fun2Proc(
    LPVOID   lpParameter       //   thread   data
);
int   tickets=100;
HANDLE   g_hEvent;

void   main()
{
  HANDLE   hThread1;
  HANDLE   hThread2;
  hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
  hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
  CloseHandle(hThread1);
  CloseHandle(hThread2);
  g_hEvent=CreateEvent(NULL,FALSE,FALSE, "tickets ");
  if(g_hEvent)
  {
    if(ERROR_ALREADY_EXISTS==GetLastError())
    {
      cout < < "only   instance   can   run! " < <endl;
      return;
    }
  }
  SetEvent(g_hEvent);
  Sleep(4000);
  CloseHandle(g_hEvent);
}

DWORD   WINAPI   Fun1Proc(
    LPVOID   lpParameter       //   thread   data
)
{
  while(TRUE)
  {
    WaitForSingleObject(g_hEvent,INFINITE);
    if(tickets> 0)
    {
      cout < < "thread1   sell   ticket   :   " < <tickets-- < <endl;
    }
    else
      break;
    SetEvent(g_hEvent);
  }  
  return   0;
}

DWORD   WINAPI   Fun2Proc(
    LPVOID   lpParameter       //   thread   data
)
{  
  while(TRUE)
  {
    WaitForSingleObject(g_hEvent,INFINITE);
    if(tickets> 0)
    {
      cout < < "thread2   sell   ticket   :   " < <tickets-- < <endl;
    }
    else
      break;
    SetEvent(g_hEvent);
  }
 
  return   0;
}  



[解决办法]
需要对全局变量的读写进行序列化处理

tickets

单核中,对一个内存地址的写入不可能同时出现,双核以上就无法保证了
[解决办法]
g_hEvent创建太晚了,应当在在创建线程前初始化

单核系统因为主线程时间片没到,因此虽然CreateThread了,但是Thread没有机会执行, 所以后创建的g_hEvent没有引起错误。但是双核系统上有一个Thread马上就分配到了另一个cpu上和主线程同时执行,此时g_hEvent还没有创建,所以Thread中的WaitSingleObject访问了一个不存在的g_hEvent(在debug模式下g_hEvent的初始化值还不是0, 是0xCCCCCCCC)当然出错啦
[解决办法]
你这个程序有至少三个问题,但是跟单核还是双核是不相干的,单双核我认为是一样的:
(1)就是楼上说的,你的CreateEvent执行太晚。
(2)主线程Sleep再长时间,理论上也不能保证子线程都已经执行完毕。
(3)你仔细分析你的程序,会发现比方说始终都是第一个子线程在运行,当地一个线程运行完后,它并没有调用SetEvent,那么第二个线程会永远等在那里,不会结束。
[解决办法]
应该跟多核有关系

热点排行