我正在创建一个使用双缓冲的线程应用程序,我试图避免潜在的死锁。主要思想是交换缓冲区线程锁定写入和读取线程。但是,交换缓冲区线程很快,因此锁定不会长时间锁定。写入和读取线程较慢但有效地共享时间片(目标),因为它们锁定不同的互斥锁。我的问题是这个设计是否存在潜在的僵局?
void *fill_back_buffer() {
while(1) {
if (0 != pthread_mutex_lock(&theBackMutex)) {
perror("Mutex lock failed (!!):");
exit(-1);
}
//should we get new data for back buffer?
pthread_cond_wait(&theBackBufferRefresh, &theBackMutex);
//fill back buffer
if (0 != pthread_mutex_unlock(&theBackMutex)) {
perror("Mutex lock failed (!!):");
exit(-1);
}
//hey we done filling the back buffer!
pthread_cond_signal(&theBackBufferFull);
}
}
void *swap_buffers() {
while(1) {
if (0 != pthread_mutex_lock(&theBackMutex)) {
perror("Mutex lock failed (!!):");
exit(-1);
}
if (0 != pthread_mutex_lock(&theFrontkMutex)) {
perror("Mutex lock failed (!!):");
exit(-1);
}
//do we have new data in the back buffer?
pthread_cond_wait(&theBackBufferFull, &theBackMutex);
//swap buffers
char* tmp;
tmp = theBufferAPtr;
theBufferAPtr = theBufferBPtr;
theBufferBPtr = tmp;
if (0 != pthread_mutex_unlock(&theFrontMutex)) {
perror("Mutex lock failed (!!):");
exit(-1);
}
if (0 != pthread_mutex_unlock(&theBackMutex)) {
perror("Mutex lock failed (!!):");
exit(-1);
}
//hey please get more data!
pthread_cond_signal(&theBackBufferRefresh);
//hey you can use front buffer now!
pthread_cond_signal(&theBufferSwapped);
}
}
int main(int argc, char *argv[]) {
//initial fill of the back buffer
pthread_cond_signal(&theBackBufferRefresh);
while(1) {
if (0 != pthread_mutex_lock(&theFrontMutex)) {
perror("Mutex lock failed (!!):");
exit(-1);
}
pthread_cond_wait(&theBufferSwapped, &theFrontMutex);
//use the front buffer and do stuff with it
if (0 != pthread_mutex_unlock(&theFrontMutex)) {
perror("Mutex lock failed (!!):");
exit(-1);
}
}
}
答案 0 :(得分:2)
条件变量应该用于表示某些(互斥保护的)共享数据的状态变化。你不能自己使用它们。考虑如果线程在另一个线程等待该条件之前发出一个条件,会发生什么。
答案 1 :(得分:1)
我没有看到你在哪里创建任何线程。我假设你创建了线程。
swap_buffers()
和fill_back_buffer()
确实包含经典的死锁实现。当swap_buffers()
等待theBackBufferFull
时,它已锁定theBackMutex
。同时,fill_back_buffer()
在设置信号theBackMutex
之前等待theBackBufferFull
。因此,永远不会发出theBackBufferFull
信号,因为无法释放theBackMutex
。这是典型的死锁条件。
答案 2 :(得分:0)
尝试不使用额外的线程进行交换。