我从文件中读取数据并在单独的线程中处理它。我试图在两个线程上并行化数据读取和处理部分,并使用具有无限循环的条件变量。 但是,我最终陷入了僵局。
char totBuf[300000];
unsigned long toLen = 0;
unsigned long lenProc = 0;
void procData()
{
while(lenProc < totLen)
{
//process data from totBuf
//increment lenProc;
}
ready = false;
if(lenProc >= totLen && totLen > 100000)
{
cv.notify_one();
unique_lock<mutex> lk(m);
cv.wait(lk, []{return totLen>0 && lenProc<totLen;});
}
}
void readData()
{
//declared so that we notify procData only once
bool firstNot = true;
while(true)
{
//read data into
//file.read(len);
//file.read(oBf, len);
memcpy(&totBuf[totLen], oBf, len);
//increment totLen
if(totLen > 10000)
cv.notify_one();
if(totLen > 100000)
{
cv.notify_one();
unique_lock<mutex> lk(m);
cv.wait_for(lk, []{return !ready;});
totLen = 0;
firstNot = true;
lenProc = 0;
}
}
}
int main(int argc, char* argv[])
{
inFile.open(argv[1], ios::in|ios::binary);
thread prod(readData);
thread cons(procSeqMsg);
prod.join();
ready = true;
cout << "prod joined\n";
cv.notify_all();
cons.join();
cout << "cons joined\n";
inFile.close();
return(0);
}
一些解释如果看起来很奇怪。虽然我已经将totBuf大小声明为300k,但是当它的100k时我将totLen重置为0,因为我从新块可能很大的文件中读取数据块。当大小达到100k时,我重置totLen以再次读取totBuf的数据。 当尺寸达到10k时,我首先通知消费者,以便可以实现最大的并发处理。 这可能是一个非常糟糕的设计,我愿意从头开始重新设计。我想要的是完全无锁实现,但对于线程来说是新手,因此这是我现在可以做的止损/最好的。