Моя проблема в том, что код для Producer и Consumer не имеет взаимоисключающих посещений буфера, вывод сбивает с толку. Потребитель будет работать, когда производитель не закончил.
Я использовал три семафора: mutex
гарантирует исключение между потоками, full
означает размер буфера, если буфер заполнен (BUFFER_SIZE
), производитель будет спать;epty
означает (BUFFER_SIZE - full
), если epty равно 0, потребитель будет спать;
void init() {
nextp = nextc = 0;
mutex = CreateSemaphore(NULL, 1, 1, NULL);
epty = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, NULL);
full = CreateSemaphore(NULL, 0, BUFFER_SIZE, NULL);
}
DWORD WINAPI producer(void* lp) {
do {
int num = rand();
WaitForSingleObject(epty, INFINITY);
WaitForSingleObject(mutex, INFINITY);
buffer[nextp] = num;
nextp = (nextp + 1) % BUFFER_SIZE;
cout << "producer create " << num << endl;
cout << "buffer:";
for (auto it : buffer)
cout << it << " ";
cout << endl;
ReleaseSemaphore(mutex, 1, NULL);
ReleaseSemaphore(full, 1, NULL);
} while (true);
}
DWORD WINAPI consumer(void* lp) {
do {
WaitForSingleObject(full, INFINITY);
WaitForSingleObject(mutex, INFINITY);
int num = buffer[nextc];
buffer[nextc] = 0;
nextc = (nextc + 1) % BUFFER_SIZE;
cout << "consumer delete " << num << endl;
cout << "buffer:";
for (auto it : buffer)
cout << it << " ";
cout << endl;
ReleaseSemaphore(mutex, 1, NULL);
ReleaseSemaphore(epty, 1, NULL);
} while (true);
}