Я пытаюсь создать программу-потребитель-продюсер, где номера производителей потребительских потоков заполняют массив, а потребительский поток печатает числа, которые заполняют массив. В настоящее время я могу заполнить массив и передавать данные взад и вперед между потоками потребителей/производителей, но я хочу, чтобы производитель создавал числа быстрее, чем потребитель обрабатывает их.Блоки потоков, когда он не предполагается
В настоящий момент количество произведено каждые 1 секунду, а количество потребляется каждые 3. Два номера должны быть созданы до того, как один из них будет потреблен, но моя продюсерская нить ждет, пока номер, который он произвел, не будет потреблен.
Я пробовал перемещаться по замкам и разблокировать мьютексы, а также сигналы, но я не получил его на работу. Следующий код производит следующий вывод:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
struct Data {
int num;
int wait_time;
};
pthread_mutex_t the_mutex;
pthread_cond_t condc, condp;
//int count = 0;
struct Data buffer[32];
void* producer(void *ptr) {
int i, w; /* counter and random wait time */
struct Data data;
int count = 0;
while(1) {
//w = rand() % 5 + 3;
w = 1;
sleep(w); /* Wait between 3 and 7 seconds */
data.num = rand() % 1000; /* Create random number to pass */
//data.wait_time = rand() % 8 + 2;
data.wait_time = 3;
pthread_mutex_lock(&the_mutex); /* lock the buffer */
while (buffer[count].num != 0) { /* while full */
//pthread_cond_signal(&condc);
pthread_cond_wait(&condp, &the_mutex);
}
//pthread_mutex_lock(&the_mutex); /* lock the buffer */
buffer[count] = data;
pthread_cond_signal(&condc); /* signal consumer */
pthread_mutex_unlock(&the_mutex);
printf("Produced %i and slept for %i seconds\n", buffer[count].num, w);
if (count != 31){
count += 1;
//printf("Producer count: %i\n", count);
}
else
count = 0;
//pthread_cond_signal(&condc); /* signal consumer */
//pthread_mutex_unlock(&the_mutex); /* unlock */
}
pthread_exit(0);
}
void* consumer(void *ptr) {
int i;
int count = 0;
//for(i = 1; i <= MAX; i++) {
while(1) {
pthread_mutex_lock(&the_mutex); /* lock th buffer */
while(buffer[count].num == 0){
//pthread_cond_signal(&condp); /* while empty */
pthread_cond_wait(&condc, &the_mutex);
}
//pthread_mutex_lock(&the_mutex);
sleep(buffer[count].wait_time);
printf("Consumed %i and slept for %i seconds\n", buffer[count].num, buffer[count].wait_time);
//pthread_mutex_lock(&the_mutex);
buffer[count].num = 0;
buffer[count].wait_time = 0;
pthread_cond_signal(&condp); /* signal producer */
pthread_mutex_unlock(&the_mutex);
if(count != 31){
count += 1;
//printf("Consumer count: %i\n", count);
}
else
count = 0;
//pthread_cond_signal(&condp); /* signal producer */
//pthread_mutex_unlock(&the_mutex); /* unlock */
}
pthread_exit(0);
}
int main(int argc, char **argv) {
pthread_t pro, con;
srand(time(NULL));
for (int i = 0; i < 32; i++) { /* Initialize buffer */
buffer[i].num = 0;
buffer[i].wait_time = 0;
}
// Initialize the mutex and condition variables
/* What's the NULL for ??? */
pthread_mutex_init(&the_mutex, NULL);
pthread_cond_init(&condc, NULL); /* Initialize consumer condition variable */
pthread_cond_init(&condp, NULL); /* Initialize producer condition variable */
// Create the threads
pthread_create(&con, NULL, consumer, NULL);
pthread_create(&pro, NULL, producer, NULL);
// Wait for the threads to finish
// Otherwise main might run to the end
// and kill the entire process when it exits.
pthread_join(con, NULL);
pthread_join(pro, NULL);
//pthread_join(&con, NULL);
//pthread_join(&pro, NULL);
// Cleanup -- would happen automatically at end of program
pthread_mutex_destroy(&the_mutex); /* Free up the_mutex */
pthread_cond_destroy(&condc); /* Free up consumer condition variable */
pthread_cond_destroy(&condp); /* Free up producer condition variable */
}
Output (программа печатает на 1-й линии через 1 секунд, затем печатает как 2-й и 3-й, в то же время, после 3-х секунд):
Produced 985 and slept for 1 seconds
Consumed 985 and slept for 3 seconds
Produced 540 and slept for 1 seconds
Я предпочел бы иметь выход выглядеть примерно так:
Produced 985 and slept for 1 seconds
Produced 540 and slept for 1 seconds
Consumed 985 and slept for 3 seconds
'while (buffer [count] .num! = 0)' Это условие, используемое 'производителем', чтобы определить, следует ли блокировать условное. Он блокирует блок производителя, как только в буфере есть что-либо. Если вам нужно другое поведение, вы должны изменить условие. Например, если вы хотите, чтобы он блокировал, если есть уже 3 элемента, то измените на: 'while (buffer [count] .num == 3)' – kaylum