Продюсер Потребительские Многопоточные проблемы печати

Я написал программу, которая имитирует проблему потребителя производителя, и столкнулся с несколькими проблемами. Это было написано с использованием Win32 API.

Я использую два семафора, полный и пустой, чтобы выполнить подсчет для буфера, в котором хранятся элементы. Существует также мьютекс для контроля доступа к критическому разделу. У меня есть две функции: одна создает элемент на основе простого расчета: нитей * 1000000 + количество, а другая потребляет его.

В буфере 10 пробелов, но, надеюсь, программа сможет работать с разным количеством пробелов и потоков. Поток Producer проходит через буфер, затем запускается снова, пока семафор не подсчитает до 10. Я сталкиваюсь с двумя проблемами, которые, похоже, тоже не могу найти решения, и при этом я не получаю много подробностей в отладчике.

1) Закомментированная часть, которая имеет функцию printf(), прерывает поток каждый раз. Ничто никогда не печатается на консоли. Я попытался использовать только строку без других выводимых переменных. Нет успеха Я нашел документацию, что printf() может столкнуться с проблемами при использовании в многопоточной среде, однако в этом случае он находится в критическом разделе и вылетает с первой попытки. Как я могу распечатать эту информацию на консоли?

2) Когда я удаляю операторы print и запускаю код, потоки все равно каждый раз заканчиваются в разных точках. Я не могу понять, почему. Предполагается, что поток производителя ожидает пустой семафор и мьютекс, помещает элемент, а затем увеличивает счетчик для полного семафора (означающего, что элемент был добавлен). Когда он достигнет 10, он должен остановиться. Поток Consumer ожидает полного семафора и мьютекса, удаляет элемент и увеличивает количество пустых семафоров. Есть ли что-то в том, как я написал это, что вызывает выход этих потоков?

Вот что я получаю:

Программа '[5348] OperatingSystem.exe' вышла с кодом 0 (0x0).

#include<stdio.h>
#include<windows.h>
#include<ctype.h>
#include<tchar.h>
#include<strsafe.h>
#include<conio.h>
#include<time.h>


#define threads 1
#define MAX 10


typedef struct objects {
HANDLE empty;
HANDLE full;
HANDLE mutex;
int buffer[10];
};


  struct objects data;


DWORD WINAPI Producers(LPVOID lpParam){
int count = 0;
int item;
while (TRUE){
    if (data.buffer[count] == 0){
        WaitForSingleObject(data.empty, INFINITE);
        WaitForSingleObject(data.mutex, INFINITE);
        item = threads * 1000000 + count;
        data.buffer[count] = item;
        //printf("Producer has produced: %d", item);
        ReleaseMutex(data.mutex);
        ReleaseSemaphore(data.full, 1, NULL);
    }
    count++;
    if (count == 10){ count = 0; }
};
}


DWORD WINAPI Consumers(LPVOID lpParam){
int count = 0;
while (TRUE){
    if (data.buffer[count] != 0){
        WaitForSingleObject(data.full, INFINITE);
        WaitForSingleObject(data.mutex, INFINITE);
        //printf("Consumer has consummed: %d", data.buffer[count]);
        data.buffer[count] = 0;
        ReleaseMutex(data.mutex);
        ReleaseSemaphore(data.empty, 1, NULL);
    }
    count++;
    if (count == 10){ count = 0; }
};



}

int main(int argc, char *argv[]) {

struct objects data;
LONG initialCount = 0;
LONG maxCount = 10;
data.empty = CreateSemaphore(NULL, maxCount, maxCount, NULL);
data.full = CreateSemaphore(NULL, initialCount, maxCount, NULL);
data.mutex = CreateMutex(NULL, FALSE, NULL);


DWORD ConsumerId[threads];
HANDLE ConsumerThread[threads];
DWORD ProducerId[threads];
HANDLE ProducerThread[threads];


for (int i = 0; i < threads; i++){
    ProducerThread[i] = CreateThread(
        NULL,
        0,
        Producers,
        NULL,
        0,
        &ProducerId[i]);


    ConsumerThread[i] = CreateThread(
        NULL,
        0,
        Consumers,
        NULL,
        0,
        &ConsumerId[i]);
}
}

0 ответов

Другие вопросы по тегам