Я создаю потоковое приложение, использующее двойную буферизацию, и пытаюсь избежать потенциальной тупиковой ситуации. Основная идея заключается в том, что поток буфера подкачки блокирует поток записи и чтения. Однако поток буфера подкачки работает быстро, поэтому блокировки не будут долго оставаться заблокированными. Потоки Write и Read работают медленнее, но эффективно разделяют временные интервалы (цель), потому что они блокируют разные мьютексы. Мой вопрос, есть ли потенциальный тупик с этим дизайном?
- 3 резьбы ... Резьба A, резьба B и резьба C.
- 2 мьютекса ... Передний мьютекс и Задний мьютекс.
- Поток A заполняет задний буфер
- Поток B меняет буфер.
- Поток C использует передний буфер.
- Поток A принимает BackMutex, заполняет задний буфер, освобождает BackMutex.
- Поток C принимает FrontMutex, использует передний буфер, освобождает FrontMutex.
- Поток B принимает BackMutex, FrontMutex, меняет местами буферы, освобождает BackMutex, освобождает Front 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);
}
}
}