在Windows 7(64位)下使用MSYS2中的Poco 1.9.0-1。
我有一个线程,发出3次Poco:Condition信号,睡眠时间为300毫秒。
我有两个线程使用两个不同的类EvListenerA和EvListenerB,它们从Poco :: Runnable扩展,并且它们正在等待相同的Poco :: Condition显示带有std :: cout的消息。
使用第一个和第二个信号没有问题,但是当启动第三个信号时,只有线程EvListenerA可以正确捕获它。
这是代码:
/*
* main.cpp
*
* Created on: 6 jun. 2019
* Author: ccortiz
*/
#include <Poco/Thread.h>
#include <Poco/Runnable.h>
#include <Poco/Condition.h>
#include <iostream>
using namespace std;
Poco::Condition condicion;
Poco::Mutex mutex;
class GenEvents:public Poco::Runnable{
public:
void run(){
cout << "Launching GenEvents!" << endl;
for (Poco::UInt32 i=0; i<3; i++){
cout << "[GenEvents] Event_" << i << endl;
condicion.broadcast();
Poco::Thread::sleep(300); //Wait 300ms.
}
cout << "Ending GenEvents!" << endl;
}
};
class EvListenerA:public Poco::Runnable{
public:
void run(){
cout << "Launching EvListenerA!" << endl;
for (Poco::UInt32 i=0; i<3; i++){
condicion.wait(mutex);
cout << " [EvListenerA] Receiving Event_" << i << endl;
}
cout << "Ending EvListenerA!" << endl;
}
};
class EvListenerB:public Poco::Runnable{
public:
void run(){
cout << "Launching EvListenerB!" << endl;
for (Poco::UInt32 i=0; i<3; i++){
condicion.wait(mutex);
cout << " [EvListenerB] Receiving Event_" << i << endl;
}
cout << "Ending EvListenerB!" << endl;
}
};
int main(void){
Poco::Thread th1; //Hilo que genera 3 eventos.
Poco::Thread th2; //Hilo que espera 3 eventos.
Poco::Thread th3; //Hilo que espera 3 eventos.
GenEvents genEvents; //Objeto que implementa el hilo generador de eventos.
EvListenerA evListenerA; //Objeto que implementa el hilo receptor de eventos.
EvListenerB evListenerB; //Objeto que implementa el hilo receptor de eventos.
th2.start(evListenerA);
th3.start(evListenerB);
Poco::Thread::sleep(500); //Espera de medio segundo.
th1.start(genEvents);
th1.join();
th2.join();
th3.join();
}
这是程序输出:
Launching EvListenerB!
Launching EvListenerA!
Launching GenEvents!
[GenEvents] Event_0
[EvListenerB] Receiving Event_0
[EvListenerA] Receiving Event_0
[GenEvents] Event_1
[EvListenerA] Receiving Event_1
[EvListenerB] Receiving Event_1
[GenEvents] Event_2
[EvListenerA] Receiving Event_2
Ending EvListenerA!
Ending GenEvents!
为什么我的输出中没有“ [[EvListenerB]正在接收事件_2”?
EvListenerB和Event_2会发生什么?
有什么主意吗?谢谢
答案 0 :(得分:1)
嗯,对我来说,这是不确定的行为。参考文献明确指出Condition
与Mutex
或FastMutex
一起使用。调用wait
时必须锁定mutex
! -它在您的代码中丢失。
来自reference的语录:
Condition对象始终与Mutex(或 FastMutex)对象。
和
解锁互斥锁(必须在调用wait()时将其锁定)并等待 在给定时间之前,一直到发出状态为止。
给定的互斥锁将在成功离开后再次锁定 功能,即使出现异常也是如此。
因此,如果您想查看所需的输出,则必须调用互斥锁上的锁定/解锁:
for (Poco::UInt32 i=0; i<3; i++)
{
mutex.lock(); // <--- lock mutex
condicion.wait(mutex);
cout << " [EvListenerA] Receiving Event_" << i << endl;
mutex.unlock(); // <--- unlock
}
对EvListenerA
和EvListenerB
类进行相同的更改。
首先,您要锁定互斥锁。然后调用wait
,将其解锁mutex
,我们一直等到发信号通知condition
,然后wait
返回并再次锁定互斥锁(从wait
返回之前) )。在退出for循环迭代之前,将调用unlock
。