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

多线程按顺序输出,该如何解决

2012-12-21 
多线程按顺序输出本来是想循环输出0,1,2的,可是为什么只输出0呢?思路是:三个线程,三个互斥信号量;线程1输

多线程按顺序输出
本来是想循环输出0,1,2的,可是为什么只输出0呢?
思路是:
三个线程,三个互斥信号量;
线程1输出时先等待信号量1然后释放信号量2;
线程2输出时先等待信号量2然后释放信号量3;
线程3输出时先等待信号量3然后释放信号量1;
初始时每个信号量都是占用状态,首先在主线程中释放信号量1,这样三个线程就跑起来了。
可是,貌似结果和我想的不一样吖…………大神指教!


#include <iostream>
#include <Windows.h>
const int Tn = 3;
HANDLE hMutex[Tn];
void PutStar(LPVOID param)
{
int w = int(param);
int nxt = (w+1)%Tn;
while(1)
{
WaitForSingleObject(hMutex[w],INFINITE);
std::cout<<w<<std::endl;
ReleaseMutex(hMutex[nxt]);
}
}

int main()
{
HANDLE t[Tn];
for (int i=0;i<Tn;i++)
{
hMutex[i] = CreateMutex(NULL,TRUE,NULL);
t[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)PutStar,(LPVOID)i,0,NULL);
}
ReleaseMutex(hMutex[0]);
WaitForMultipleObjects(Tn,t,TRUE,INFINITE);
}

[最优解释]
用事件EVENT吧,互斥量是与线程绑定的,主线程创建,并设置true,主线程拥有互斥量,你在子线程里releasemutex是没有用的,因为占有互斥量的是主线程而不是子线程。
另外用法自己多看下msdn就知道了,如果一个线程占有互斥量,那么这个线程在没有release之前再wait是不会阻塞的,毕竟线程自身已经占有了互斥量,没必要跟自己过不去,只是wait了几次就要release几次。
[其他解释]
while(1)
    {
        WaitForSingleObject(hMutex[w],INFINITE);
        std::cout<<w<<std::endl;
        ReleaseMutex(hMutex[nxt]);
    }

死循环,看不出来?
[其他解释]
引用:
while(1)
    {
        WaitForSingleObject(hMutex[w],INFINITE);
        std::cout<<w<<std::endl;
        ReleaseMutex(hMutex[nxt]);
    }

死循环,看不出来?

循环第二次的时候在Wait处不会阻塞吗?为什么呢?
[其他解释]
推荐本书,windows核心编程,上面讲解的很清楚。
[其他解释]
引用:
用事件EVENT吧,互斥量是与线程绑定的,主线程创建,并设置true,主线程拥有互斥量,你在子线程里releasemutex是没有用的,因为占有互斥量的是主线程而不是子线程。
另外用法自己多看下msdn就知道了,如果一个线程占有互斥量,那么这个线程在没有release之前再wait是不会阻塞的,毕竟线程自身已经占有了互斥量,没必要跟自己过不去,只是wait了几次就要re……

多谢了!用Event就可以了,以前没有仔细看Mutex的Remarks。。
[其他解释]
修改后代码:
#include <iostream>
#include <Windows.h>
const int Tn = 3;
INT turn = 0;
HANDLE hEvent;
void PutStar(LPVOID param)
{
int w = int(param);
int nxt = (w+1)%Tn;
int pct = 10;
while(pct--)
{
while(turn!=w)
WaitForSingleObject(hEvent,INFINITE);
std::cout<<w<<std::endl;
turn = nxt;
SetEvent(hEvent);
}
}

int main()
{
HANDLE t[Tn];
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
for (int i=0;i<Tn;i++)
{
t[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)PutStar,(LPVOID)i,0,NULL);
}
turn = 0;
SetEvent(hEvent);
WaitForMultipleObjects(Tn,t,TRUE,INFINITE);
}

热点排行