C双缓冲实现死锁?

时间:2011-03-15 20:14:11

标签: c multithreading pthreads deadlock mutex

我正在创建一个使用双缓冲的线程应用程序,我试图避免潜在的死锁。主要思想是交换缓冲区线程锁定写入和读取线程。但是,交换缓冲区线程很快,因此锁定不会长时间锁定。写入和读取线程较慢但有效地共享时间片(目标),因为它们锁定不同的互斥锁。我的问题是这个设计是否存在潜在的僵局?

  • 3个线程......线程A,线程B和线程C.
  • 2个互斥锁...前互斥锁和后互斥锁。

  • 线程A填充后台缓冲区
  • 线程B交换缓冲区。
  • 线程C使用前缓冲区。

  • 线程A接受BackMutex,填充后台缓冲区,释放theBackMutex。
  • 线程C使用FrontMutex,使用前缓冲区,释放theFrontMutex。
  • 线程B使用theBackMutex,theFrontMutex,交换缓冲区,释放theBackMutex,释放theFront Mutex

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);
        } 
    }
}

3 个答案:

答案 0 :(得分:2)

条件变量应该用于表示某些(互斥保护的)共享数据的状态变化。你不能自己使用它们。考虑如果线程在另一个线程等待该条件之前发出一个条件,会发生什么。

答案 1 :(得分:1)

我没有看到你在哪里创建任何线程。我假设你创建了线程。

swap_buffers()fill_back_buffer()确实包含经典的死锁实现。当swap_buffers()等待theBackBufferFull时,它已锁定theBackMutex。同时,fill_back_buffer()在设置信号theBackMutex之前等待theBackBufferFull。因此,永远不会发出theBackBufferFull信号,因为无法释放theBackMutex。这是典型的死锁条件。

答案 2 :(得分:0)

尝试不使用额外的线程进行交换。