gpt4 book ai didi

c - 线程在不应该阻塞时阻塞

转载 作者:行者123 更新时间:2023-12-03 06:23:04 24 4
gpt4 key购买 nike

我正在尝试创建一个消费者-生产者程序,其中消费者线程生产者用数字填充数组,消费者线程打印填充数组的数字。目前,我可以填充数组并在消费者/生产者线程之间来回传递数据,但我希望生产者创建数字的速度比消费者处理它们的速度快。

目前,每 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 */

}

输出(程序在1秒后打印第一行,然后在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

最佳答案

消费者锁定互斥锁,然后休眠 3 秒。因此,生产者必须等待消费者完成其工作/ sleep ,然后才能生产其他东西。当锁到位时,避免休眠任一线程。

编辑:只是稍微编辑了你的代码,这似乎可以在没有信号等的情况下工作。尝试一下:

#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;
struct Data buffer[32];

void* producer(void *ptr) {
int i, w; /* counter and random wait time */
struct Data data;
int count = 0;

while(1) {
printf("prod count %d\n",count);
w = 1;
sleep(w);
data.num = rand() % 1000;
data.wait_time = 3;

while (buffer[count].num != 0) {
printf("buffer full, count = %d\n", count);
sleep(1);
}

// Only using the mutex when we want to change the variable.
pthread_mutex_lock(&the_mutex);
buffer[count] = data;
pthread_mutex_unlock(&the_mutex);

printf("Produced %i and slept for %i seconds\n", buffer[count].num, w);

if (count != 31){
count += 1;
}
else
count = 0;
}
pthread_exit(0);
}

void* consumer(void *ptr) {
int i;
int count = 0;

while(1) { /* lock th buffer */
printf("cons count %d\n",count);
while(buffer[count].num == 0){
printf("buffer empty, count = %d\n", count);
sleep(1);
}

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_mutex_unlock(&the_mutex);

if(count != 31){
count += 1;
//printf("Consumer count: %i\n", count);
}
else {
count = 0;
}
}
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 */
}

关于c - 线程在不应该阻塞时阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36390831/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com