#include #include #include #include #include const int bufSize = 10; int buf[bufSize] ; //буфер int front = 0 ; //индекс для чтения из буфера int rear = 0 ; //индекс для записи в буфер int count = 0 ; //количество занятых ячеек буфера unsigned int seed = 101; // инициализатор генератора случайных чисел pthread_mutex_t mutex ; // мьютекс для условных переменных // поток-писатель блокируется этой условной переменной, // когда количество занятых ячеек становится равно bufSize pthread_cond_t not_full ; // поток-читатель блокируется этой условной переменной, // когда количество занятых ячеек становится равно 0 pthread_cond_t not_empty ; //стартовая функция потоков – производителей (писателей) void *Producer(void *param) { int pNum = *((int*)param); int data, i ; while (1) { //создать элемент для буфера data = rand() % 11 - 5 ; //поместить элемент в буфер pthread_mutex_lock(&mutex) ; //защита операции записи //заснуть, если количество занятых ячеек равно сто while (count == bufSize ) { pthread_cond_wait(¬_full, &mutex) ; } //запись в общий буфер buf[rear] = data ; rear = (rear+1)%bufSize ; count++ ; //появилась занятая ячейка //конец критической секции pthread_mutex_unlock(&mutex) ; //разбудить потоки-читатели после добавления элемента в буфер pthread_cond_broadcast(¬_empty) ; printf("Producer %d: Writes value = %d to cell [%d]\n", pNum, data, rear) ; sleep(2); } return NULL; } //стартовая функция потоков – потребителей (читателей) void *Consumer(void *param) { int cNum = *((int*)param); int result ; while (1) { //извлечь элемент из буфера pthread_mutex_lock(&mutex) ; //защита операции чтения //заснуть, если количество занятых ячеек равно нулю while (count == 0) { pthread_cond_wait(¬_empty, &mutex) ; } //изъятие из общего буфера – начало критической секции result = buf[front] ; front = (front+1)%bufSize ; //критическая секция count-- ; //занятая ячейка стала свободной //конец критической секции pthread_mutex_unlock(&mutex) ; //разбудить потоки-писатели после получения элемента из буфера pthread_cond_broadcast(¬_full) ; //обработать полученный элемент printf("Consumer %d: Reads value = %d from cell [%d]\n", cNum, result, front) ; sleep(5); } return NULL; } int main() { srand(seed); int i ; //инициализация мутексов и семафоров pthread_mutex_init(&mutex, NULL) ; pthread_cond_init(¬_full, NULL) ; pthread_cond_init(¬_empty, NULL) ; //запуск производителей pthread_t threadP[3] ; int producers[3]; for (i=0 ; i<3 ; i++) { producers[i] = i + 1; pthread_create(&threadP[i],NULL,Producer, (void*)(producers+i)) ; } //запуск потребителей pthread_t threadC[4] ; int consumers[4]; for (i=0 ; i < 4 ; i++) { consumers[i] = i + 1; pthread_create(&threadC[i],NULL,Consumer, (void*)(consumers+i)) ; } //пусть главный поток тоже будет потребителем int mNum = 0; Consumer((void*)&mNum) ; return 0; }