Code: Select all
#include <wx/wx.h>
#include <queue>
#include <iostream>
typedef std::queue<int> fifo;
class AThread : public wxThread
{
public:
AThread();
virtual void *Entry();
//virtual void OnExit();
};
class BThread : public wxThread
{
public:
BThread();
virtual void *Entry();
//virtual void OnExit();
};
fifo fifoa;
wxCriticalSection csfifoa;
wxMutex mutFifoALow,mutFifoAHigh;
wxCondition condFifoALow(mutFifoALow),condFifoAHigh(mutFifoAHigh);
bool fifoa_low()
{
wxCriticalSectionLocker locker(csfifoa);
return fifoa.size()<5;
}
bool fifoa_high()
{
wxCriticalSectionLocker locker(csfifoa);
return fifoa.size()>10;
}
int main()
{
wxInitialize();
AThread* ath=new AThread;
BThread* bth=new BThread;
ath->Create();
bth->Create();
ath->Run();
bth->Run();
wxSleep(10);
std::cout<<"delete both threads"<<std::endl;
ath->Delete();
bth->Delete();
std::cout<<"exit"<<std::endl;
wxSleep(6);
return 0;
}
AThread::AThread():wxThread()
{
}
void *AThread::Entry()
{
int c=0;
while(!TestDestroy()){
if(fifoa_high()){
std::cerr<<"A: wait !fifoa_high"<<std::endl;
condFifoALow.Signal();
mutFifoAHigh.Lock();
condFifoAHigh.Wait();
std::cerr<<"A: wait !fifoa_high end"<<std::endl;
}
csfifoa.Enter();
fifoa.push(c++);
csfifoa.Leave();
if(!fifoa_low()){
condFifoALow.Signal();
}
}
return NULL;
}
BThread::BThread():wxThread()
{
}
void *BThread::Entry()
{
int c;
while(!TestDestroy()){
if(fifoa_low()){
std::cerr<<"B: wait !fifoa_low"<<std::endl;
condFifoAHigh.Signal();
mutFifoALow.Lock();
condFifoALow.Wait();
std::cerr<<"B: wait !fifoa_low ends"<<std::endl;
}
csfifoa.Enter();
c=fifoa.front();
fifoa.pop();
std::cout<<c<<" \tfifo_size="<<fifoa.size()<<std::endl;
csfifoa.Leave();
if(!fifoa_high()){
condFifoAHigh.Signal();
}
}
return NULL;
}
Thread A is writing to a FIFO (queue<int>) while B is reading from it.
I use wxCondition for sync purpose.
However, I found the above code behaves abnormally.
In particular, both threads will wait indefinitely (deadlock)
A sample output is like below:
Code: Select all
1046 fifo_size=10
1047 fifo_size=9
A: wait !fifoa_high
1048 fifo_size=8
1049 fifo_size=7
1050 fifo_size=6
A: wait !fifoa_high end1051 fifo_size=5
1052 fifo_size=4
B: wait !fifoa_low
A: wait !fifoa_high
dead here!!!
Help is highly appreciated.