应该想让它分别显示0,1,2。结果显示0,1,2,3。(对顺序不要求)
请问怎么解决?int u=0;
CCriticalSection cs;
以上在CPP文件的开头定义
......
while (u<3)
{
  cs.Lock();
  AfxBeginThread(ThreadDown,NULL);
}
全局函数ThreadDown的定义如下
UINT ThreadDown(LPVOID iP)
{
   int i=u;
   u++;
   cs.Unlock();
   CString iname;//以下3句用于显示i
   iname.Format("%d",i);
   AfxMessageBox(iname);
    ....
}

解决方案 »

  1.   

    以下是在void CMyAntsDlg::OnOK()函数中
    while (u<3)
    {
      cs.Lock();
      AfxBeginThread(ThreadDown,NULL);
    }
      

  2.   

    当在第3次线程开启的时候,程序首先返回了while,而此时线程中u++未执行,u仍然为2,所以会多出一次判断来,此法可能会显示为3次,没试过,这是一个线程优先级的问题
      

  3.   

    当在第3次线程开启的时候,程序首先返回了while,而此时线程中u++未执行,u仍然为2。
    但是此时线程由于还没有u++,所以还没有解锁阿(cs.Unlock())。
    我把
    while (u<3)
    {
      cs.Lock();
      AfxBeginThread(ThreadDown,NULL);
    }
    改成
    while (u<3)
    {
      cs.Lock();
      if (u<3)
      {
         AfxBeginThread(ThreadDown,NULL);
       }  
    }
    也不行的,显示0,1,2,3到底怎么回事啊?郁闷死了,这个问题搞了2天了
      

  4.   

    cs.Unlock();  // 这个没有效果的,因为只有 cs 的拥有者才能 Unlock,调用 cs.Lock(); 是你的主线程,所以 cs 当前的拥有者是主线程。正确的做法:
    do{
      cs.Unlock();
      AfxBeginThread(ThreadDown,NULL);
      cs.Lock();
    } while (u < 3);UINT ThreadDown(LPVOID iP)
    {
       cs.Lock();
       u ++;
       cs.Unlock();   ....
    }
      

  5.   

    to  In355Hz
    1。只有 cs 的拥有者才能 Unlock,子线程不能Unlock的话,那么为什么
    while (u<3)
    {
      cs.Lock();
      AfxBeginThread(ThreadDown,NULL);
    }
    能一直运行,显示0,1,2,3呢?
    2。你的做法我试了,造成死机。
       我于是试着将
      do{
      cs.Unlock();//语句1
      AfxBeginThread(ThreadDown,NULL);
      cs.Lock();//语句2
    } while (u < 3);
    中的语句1和2调换,也不行。
    我对你的代码有些不明白,能实现多线程并发吗?
    因为我各个线程其实是要做很多其它事情的
    谢谢你的回复
      

  6.   

    farfh(远)说的对:
      主线程是先执行while判断,然后被阻塞的,所以会多执行一次。
    你的程序没有对变量u成功保护,主线程的读操作while(u<3),和子线程的写u++会冲突
      

  7.   

    那段代码的确有问题,因为 AfxBeginThread 后线程并没有立即执行,结果 while(u < 3) {} 因为 u 一直为 0 ,形成了死循环。这样可以解决问题do{
      cs.Unlock();
      AfxBeginThread(ThreadDown,NULL);
      Sleep(10);
      cs.Lock();
    } while (u < 3);但是不太好。还是用 Event 同步,CCriticalSection 毕竟是用来保护共享变量的// 全局变量
    HANDLE hEvent = NULL;
    long volatile u = 0; // 最好加 volatile 关键字...
    hEvent = ::CreateEvent(NULL, FALSE/*自动重置*/, FALSE/*初始无信号*/, NULL);while(u < 3) 
    {
        AfxBeginThread(ThreadDown, NULL);
        ::WaitForSingleObject(hEvent, INFINITE);
    }UINT ThreadDown(LPVOID iP)
    {
       InterlockedIncrement(&u); // 最好用 InterlockedIncrement 代替 u ++   ::SetEvent(hEvent); // 设置信号   ....
    }
      

  8.   

    呵呵,如果不用Event的话,只能用数量限制为1的信号灯。有些书上说这个跟互斥是一样的,但我看不一样。因为信号灯没有所有者的概念,但互斥和临界区有。