现在有3个线程,需要进行同步处理,现在不知道用的CEvent,还是通过对线程的挂起和恢复来实现,那种要好一些.
如下:
用CEvent;
CEvent event1(FALSE,FALSE,NULL,NULL); //自动事件
CEvent event2(FALSE,TRUE,NULL,NULL);  //手动事件
//发送线程
UINT thread1(LPVOID lParam)
{
DWORD iRet;
while(1)
{
//发送数据完成后,就开启接收线程,等待数据接收
/....../
event2.SetEvent();//开启接收线程

//如果100ms没有收到应该收到的数据,就不在等待.
iRet = WaitForSingleObject(event1, 100);
switch()
{
case WAIT_TIMEOUT:
event2.ResetEvent();//接收超时,挂起接收线程,
 //这里用thread2->suspendThread(),来代替好不
break;
default:
break;
}
sleep(10);
}
}
//接收线程,查询读取数据
UINT thread2(LPVOID lParam)
{
    while(1)
    {
     WaitForSingleObject(event2, INIFINTE);
     //读取数据,如果在100ms里读取到50个数据,就自动停止
     count += readdata();
    
     if(count == 50)
     { PostMessage();//给主线程显示接收正确的数据
     event2.ResetEvent(); 
     event1.SetEvent();
     }
    }
}
//主线程,界面显示数据等等.
UINT thread3(LPVOID lParam)
{
}用挂起和恢复线程实现
//发送线程
UINT thread1(LPVOID lParam)
{
DWORD iRet;
while(1)
{
//发送数据完成后,就开启接收线程,等待数据接收
/....../
//开启接收线程
while(thread2->ResumeThread() == 0xFFFFFFFF){}
//如果100ms没有收到应该收到的数据,就不在等待.
iRet = WaitForSingleObject(event1, 100);
switch()
{
case WAIT_TIMEOUT:
//接收超时,挂起接收线程,
  while(thread2->suspendThread() == 0xFFFFFFFF){}
break;
default:
break;
}

sleep(10);
}
}
//接收线程,查询读取数据
线程创建是就是挂起状态
UINT thread2(LPVOID lParam)
{
    while(1)
    {   
     //读取数据,如果在100ms里读取到50个数据,就自动停止
     count += readdata();
    
     if(count == 50)
     {
     PostMessage();//给主线程显示接收正确的数据
     while(thread2->suspendThread() == 0xFFFFFFFF){} 
     event1.SetEvent();
     }
    }
}请问各位大侠还有什么好的方法吗?小弟在此谢了

解决方案 »

  1.   

    EnterCriticalSection()
    ..............
    ..代码........
    ..............
    LeaveCriticalSection()
    这样其中"代码"就没有同步问题了
      

  2.   

    用Event吧,挂线程的办法不精确.
      

  3.   

    各位也许我的代码写的有点乱,我的意思就是event可以实现的方法,其实用挂线程一样可以实现,既然是目的都是一个时间只有一个线程可以运行,那我自己手动控制它休息和内核调度让它等待应该结果一样,目的都一样,我想知道这两个方式有什么效率不同吗?
      

  4.   

    用Event更好,调度起来更灵活
      

  5.   

    呵呵,其实一楼的大哥已经解释的很形象生动了 :)
    毫无疑问用事件的方式比用挂起的方式更有符合习惯,顺便说一下,我没有看到在你的线程挂起以后怎么唤醒呢?
    至于说到效率问题,两种方式的效率肯定是不一样的,因为线程的调度是在内核模式进行的,我们使用的都是微软提供的用户模式的API,我们很难了解这两种方式在系统内部是怎么处理的,那么为什么不采用一种微软文档里面有详细资料,而且使用非常普遍的同步方式呢?
      

  6.   

    hmm,看到ResumeThread了,考虑到你说的情况比较特殊,因为你其他的几个线程除了接收几个数据以外没有别的事情做的话,采用你说的suspend/resume的方式也是挺好的。
    如果用event的方式的话,有个好处就是各个线程平时可以自行其事,只有到相互之间需要同步的时候再同步就好。其实这两种处理方式只是大家考虑问题的角度不同罢了。
      

  7.   

    实际上在正确意义来讲,线程都几乎是平等的,如果没设置优先级的话感觉用resume,suspend 都是没办法协调线程运行的次序的因为线程是强占式运行的,都不可能控制的,只能用锁来做点上的动作的同步,而做不到实际的同步因此最好还是用系统锁来解决
      

  8.   

    还有就是,LZ上面的代码结构个人觉得优点问题,应该一个主线程再加一个工作线程就够了主线程->只做界面消息处理,和一些小过程工作线程->做收跟发,同时处理,不应该一个线程就只有一个功能这样的话,工作线程的多线程才有意义
      

  9.   

    还有就是,LZ上面的代码结构个人觉得优点问题,应该一个主线程再加一个工作线程就够了主线程->只做界面消息处理,和一些小过程工作线程->做收跟发,同时处理,不应该一个线程就只有一个功能这样的话,工作线程的多线程才有意义
    =========================================
    这种观念对于某些实际应用上的设计有点不太理想.更何况现在都讲求I/O重叠,也就是在一条线路上同时收发,并且互不干扰(此时一方出错,处理的时候最好不要使用closesocket,而采用shutdown).
      

  10.   

    多谢各位的赐教,因为出差了,最近刚刚回来才上网,看见大家的讲解很高兴,谢谢了。
    dronly(蚊子) 可能我没有把实际情况给你说清楚,unsigned()兄的说法可以对你解释了。现在我还是选择了CreateEvent来实现,新问题又出来了。我有个全局变量a,只会在一个线程thread1中会进行a赋值操作,其他thread2线程只会进行a读取操作,所以我没有进行互斥保护,但是现在偶尔会出现在线程thread2读值操作以后setevent,thread1中waitforsingleobject()同步以后,这个a值偶尔会发生改变。真不知道怎么会变,因为a的赋值在thread1中。
      

  11.   

    UINT thread1(LPVOID lParam)
    {
    DWORD iRet;
    while(1)
    {
    event2.SetEvent();//开启接收线程//如果100ms没有收到应该收到的数据,就不在等待.
    iRet = WaitForSingleObject(event1, 100);
    switch()
    {
    case WAIT_TIMEOUT:
    event2.ResetEvent();//接收超时,挂起接收线程,
     //这里用thread2->suspendThread(),来代替好不
    break;
    case WAIT_OBJECT_0:
    //发送数据完成后,就开启接收线程,等待数据接收
    /....../
    ~~~~~~~~~~~~~~~~~~~应该在收到event1这个事件(即收到50个)后再发送吧???
                       不然没收满50个也在不停的发
                       发送完以后还要清零
    break;
    }
    sleep(10);
    }
    }
      

  12.   

    不是这样,在接收线程里面就已经接收满足条件,才返回WAIT_BOJECT_0.
    发完以后肯定是清0了。
    现在是那个全局变量要变,很奇怪?