生产者消费者c语言代码_生产者消费者问题、父子进程、信号量(IPC机制):代码分享...

时间: 2023-09-19 20:05:56 浏览: 54
### 回答1: 下面是一个基于信号量实现的生产者消费者问题的C语言代码: ``` #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <semaphore.h> #define BUFFER_SIZE 5 // 缓冲区大小 int buffer[BUFFER_SIZE]; // 缓冲区数组 int in = 0; // 生产者放置产品的位置 int out = 0; // 消费者取产品的位置 sem_t empty_sem; // 同步信号量,表示缓冲区中空余的数量 sem_t full_sem; // 同步信号量,表示缓冲区中已经存放的产品数量 pthread_mutex_t mutex; // 互斥锁,保证同一时刻只有一个线程访问缓冲区 void *producer(void *arg); void *consumer(void *arg); int main() { pthread_t tid1, tid2; // 初始化信号量和互斥锁 sem_init(&empty_sem, 0, BUFFER_SIZE); sem_init(&full_sem, 0, 0); pthread_mutex_init(&mutex, NULL); // 创建生产者和消费者线程 pthread_create(&tid1, NULL, producer, NULL); pthread_create(&tid2, NULL, consumer, NULL); // 等待线程结束 pthread_join(tid1, NULL); pthread_join(tid2, NULL); // 销毁信号量和互斥锁 sem_destroy(&empty_sem); sem_destroy(&full_sem); pthread_mutex_destroy(&mutex); return 0; } void *producer(void *arg) { int i, item; for (i = 0; i < 10; i++) { // 生成一个产品 item = rand() % 100; // 等待缓冲区中空闲的位置 sem_wait(&empty_sem); // 获取缓冲区互斥锁 pthread_mutex_lock(&mutex); // 将产品放入缓冲区 buffer[in] = item; printf("Producer put item %d at %d\n", item, in); in = (in + 1) % BUFFER_SIZE; // 释放缓冲区互斥锁 pthread_mutex_unlock(&mutex); // 发送信号,表示缓冲区中已经有一个产品 sem_post(&full_sem); // 休眠一段时间 sleep(rand() % 3); } pthread_exit(NULL); } void *consumer(void *arg) { int i, item; for (i = 0; i < 10; i++) { // 等待缓冲区中有产品 sem_wait(&full_sem); // 获取缓冲区互斥锁 pthread_mutex_lock(&mutex); // 从缓冲区中取出一个产品 item = buffer[out]; printf("Consumer get item %d from %d\n", item, out); out = (out + 1) % BUFFER_SIZE; // 释放缓冲区互斥锁 pthread_mutex_unlock(&mutex); // 发送信号,表示缓冲区中空闲的位置增加了一个 sem_post(&empty_sem); // 休眠一段时间 sleep(rand() % 3); } pthread_exit(NULL); } ``` 这个程序定义了一个缓冲区数组,一个生产者和一个消费者。生产者不断生成随机数,并将它们放入缓冲区中,消费者不断从缓冲区中取出随机数并打印出来。缓冲区的大小为5,程序运行10次后结束。在程序中使用了信号量和互斥锁来保证线程之间的同步和互斥。 ### 回答2: 生产者消费者问题是经典的同步问题,通常用于说明多进程/多线程之间的协作关系。下面是一个使用C语言实现的生产者消费者问题的代码分享: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <semaphore.h> #define BUFFER_SIZE 10 // 缓冲区大小 int buffer[BUFFER_SIZE]; // 缓冲区 int buffer_index = 0; // 缓冲区索引 sem_t full, empty; // 计数信号量 // 生产者线程 void *producer(void *id) { int producer_id = *((int *)id); while (1) { int item = rand() % 100; // 产生一个随机数作为生产的物品 sem_wait(&empty); // 等待缓冲区有空位置可以放入 sem_wait(&mutex); // 上锁,防止多个生产者同时操作缓冲区 buffer[buffer_index] = item; // 将物品放入缓冲区 printf("Producer %d produced item %d\n", producer_id, item); buffer_index++; sem_post(&mutex); // 解锁 sem_post(&full); // 增加一个物品到缓冲区,表示有物品可以被消费 } pthread_exit(NULL); } // 消费者线程 void *consumer(void *id) { int consumer_id = *((int *)id); while (1) { sem_wait(&full); // 等待缓冲区有物品可以消费 sem_wait(&mutex); // 上锁,防止多个消费者同时操作缓冲区 int item = buffer[--buffer_index]; // 从缓冲区取出物品 printf("Consumer %d consumed item %d\n", consumer_id, item); sem_post(&mutex); // 解锁 sem_post(&empty); // 增加一个空位置到缓冲区,表示有空位置可以放入物品 sleep(1); // 模拟消费时间 } pthread_exit(NULL); } int main() { sem_init(&mutex, 0, 1); // 初始化互斥信号量 sem_init(&full, 0, 0); // 初始化满的信号量为0 sem_init(&empty, 0, BUFFER_SIZE); // 初始化空的信号量为缓冲区大小 pthread_t producer_thread, consumer_thread; int producer_id = 1, consumer_id = 1; pthread_create(&producer_thread, NULL, producer, (void *)&producer_id); pthread_create(&consumer_thread, NULL, consumer, (void *)&consumer_id); pthread_join(producer_thread, NULL); pthread_join(consumer_thread, NULL); sem_destroy(&mutex); sem_destroy(&full); sem_destroy(&empty); return 0; } ``` 以上是一个基于父子进程以及信号量实现的生产者消费者问题的代码分享。在代码中,使用了两个线程分别代表生产者和消费者,通过互斥信号量mutex和计数信号量full、empty实现线程间的同步和互斥操作。 ### 回答3: 生产者消费者问题是一种经典的多线程同步问题。在生产者消费者问题中,有两种角色:生产者和消费者。生产者负责生产产品,消费者负责消费产品。这两种角色通过共享的缓冲区进行交互。 以下是一个使用C语言编写的基于父子进程和信号量机制的生产者消费者问题的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/sem.h> #define BUFFER_SIZE 5 #define NUM_PRODUCERS 2 #define NUM_CONSUMERS 2 typedef struct { int buffer[BUFFER_SIZE]; int in; int out; } Buffer; Buffer sharedBuffer; union semun { int val; struct semid_ds *buf; unsigned short int *array; }; void produce(int item) { sharedBuffer.buffer[sharedBuffer.in] = item; sharedBuffer.in = (sharedBuffer.in + 1) % BUFFER_SIZE; } int consume() { int item = sharedBuffer.buffer[sharedBuffer.out]; sharedBuffer.out = (sharedBuffer.out + 1) % BUFFER_SIZE; return item; } void producer(int semid) { int i; for (i = 0; i < NUM_PRODUCERS; i++) { sleep(rand() % 3); // 模拟生产过程 semctl(semid, 0, -1); // P操作,申请临界区资源 int item = rand() % 100; produce(item); printf("Producer %d produced item: %d\n", getpid(), item); semctl(semid, 0, 1); // V操作,释放临界区资源 } exit(0); } void consumer(int semid) { int i; for (i = 0; i < NUM_CONSUMERS; i++) { sleep(rand() % 3); // 模拟消费过程 semctl(semid, 0, -1); // P操作,申请临界区资源 int item = consume(); printf("Consumer %d consumed item: %d\n", getpid(), item); semctl(semid, 0, 1); // V操作,释放临界区资源 } exit(0); } int main() { int pid; int semid; srand(time(NULL)); semid = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT); // 创建一个信号量集 union semun arg; arg.val = 1; semctl(semid, 0, SETVAL, arg); // 初始化信号量 pid = fork(); if (pid < 0) { fprintf(stderr, "Fork failed\n"); return 1; } else if (pid > 0) { // 父进程作为生产者 producer(semid); } else { // 子进程作为消费者 consumer(semid); } return 0; } ``` 在代码中,定义了一个缓冲区结构体`Buffer`来存储生产者和消费者共享的缓冲区。`produce`函数用于将产品放入缓冲区,`consume`函数用于从缓冲区中取出产品。 `producer`函数和`consumer`函数分别表示生产者进程和消费者进程的代码逻辑。在这里,我们使用`semget`函数创建了一个信号量集,通过`semctl`函数对信号量进行P操作(申请临界区资源)和V操作(释放临界区资源)。 在`main`函数中,使用`fork`函数创建了一个子进程,父进程作为生产者,子进程作为消费者。 以上是一个简单的生产者消费者问题的C语言代码示例,通过父子进程和信号量机制实现了多线程的同步。

相关推荐

生产者消费者问题是一个经典的同步问题,可以通过信号量来解决。 信号量是一种同步机制,用于协调多个进程或线程之间的操作。它可以用来实现互斥、同步和通信等功能。在生产者消费者问题中,可以使用两个信号量来实现同步,一个用于表示有空闲的缓冲区可以写入,一个用于表示有数据可以读取。 以下是一个用信号量解决生产者消费者问题的示例代码: c #include <stdio.h> #include <stdlib.h> #include #include <semaphore.h> #define BUFFER_SIZE 5 #define PRODUCER_NUM 2 #define CONSUMER_NUM 2 sem_t empty, full, mutex; int buffer[BUFFER_SIZE]; int in = 0, out = 0; void *producer(void *arg) { int id = *((int *)arg); while (1) { int item = rand() % 100 + 1; sem_wait(&empty); sem_wait(&mutex); buffer[in] = item; printf("Producer %d produced item %d\n", id, item); in = (in + 1) % BUFFER_SIZE; sem_post(&mutex); sem_post(&full); sleep(rand() % 3); } pthread_exit(NULL); } void *consumer(void *arg) { int id = *((int *)arg); while (1) { sem_wait(&full); sem_wait(&mutex); int item = buffer[out]; printf("Consumer %d consumed item %d\n", id, item); out = (out + 1) % BUFFER_SIZE; sem_post(&mutex); sem_post(&empty); sleep(rand() % 3); } pthread_exit(NULL); } int main() { pthread_t producer_threads[PRODUCER_NUM], consumer_threads[CONSUMER_NUM]; sem_init(&empty, 0, BUFFER_SIZE); sem_init(&full, 0, 0); sem_init(&mutex, 0, 1); int i, id[PRODUCER_NUM + CONSUMER_NUM]; for (i = 0; i < PRODUCER_NUM; i++) { id[i] = i; pthread_create(&producer_threads[i], NULL, producer, &id[i]); } for (i = 0; i < CONSUMER_NUM; i++) { id[PRODUCER_NUM + i] = i; pthread_create(&consumer_threads[i], NULL, consumer, &id[PRODUCER_NUM + i]); } for (i = 0; i < PRODUCER_NUM; i++) { pthread_join(producer_threads[i], NULL); } for (i = 0; i < CONSUMER_NUM; i++) { pthread_join(consumer_threads[i], NULL); } sem_destroy(&empty); sem_destroy(&full); sem_destroy(&mutex); return 0; } 在本示例代码中,empty、full和mutex是三个信号量,分别用于表示空闲缓冲区数、有数据缓冲区数和互斥访问缓冲区。在生产者线程中,先使用sem_wait(&empty)等待有空闲缓冲区可以写入,然后使用sem_wait(&mutex)获取互斥访问权,向缓冲区写入数据,然后释放互斥访问权和写入信号量full,并睡眠一段时间。在消费者线程中,先使用sem_wait(&full)等待有数据缓冲区可以读取,然后使用sem_wait(&mutex)获取互斥访问权,从缓冲区读取数据,然后释放互斥访问权和空闲信号量empty,并睡眠一段时间。 这样通过信号量的机制,就可以实现多个生产者和多个消费者并发地操作缓冲区,避免了数据竞争和死锁等问题。
以下是一个简单的生产者消费者问题的C语言代码,使用信号量来同步生产者和消费者的操作: c #include <stdio.h> #include <stdlib.h> #include #include <semaphore.h> #define BUFFER_SIZE 5 // 缓冲区大小 #define PRODUCER_NUM 3 // 生产者数量 #define CONSUMER_NUM 2 // 消费者数量 #define ITEM_NUM 10 // 每个生产者/消费者要生产/消费的物品数量 int buffer[BUFFER_SIZE]; // 缓冲区 int in = 0, out = 0; // 缓冲区的输入和输出指针 sem_t empty, full, mutex; // 信号量 void *producer(void *arg) { int id = *((int *)arg); for (int i = 0; i < ITEM_NUM; i++) { // 生产一个物品 int item = rand() % 1000; // 等待空缓冲区 sem_wait(&empty); sem_wait(&mutex); // 将物品放入缓冲区 buffer[in] = item; printf("Producer %d: produce item %d at buffer[%d]\n", id, item, in); in = (in + 1) % BUFFER_SIZE; sem_post(&mutex); sem_post(&full); } return NULL; } void *consumer(void *arg) { int id = *((int *)arg); for (int i = 0; i < ITEM_NUM; i++) { // 等待满缓冲区 sem_wait(&full); sem_wait(&mutex); // 取出一个物品 int item = buffer[out]; printf("Consumer %d: consume item %d at buffer[%d]\n", id, item, out); out = (out + 1) % BUFFER_SIZE; sem_post(&mutex); sem_post(&empty); // 消耗物品 sleep(1); } return NULL; } int main() { // 初始化信号量 sem_init(&empty, 0, BUFFER_SIZE); sem_init(&full, 0, 0); sem_init(&mutex, 0, 1); // 创建生产者线程 pthread_t producers[PRODUCER_NUM]; int producer_ids[PRODUCER_NUM]; for (int i = 0; i < PRODUCER_NUM; i++) { producer_ids[i] = i; pthread_create(&producers[i], NULL, producer, &producer_ids[i]); } // 创建消费者线程 pthread_t consumers[CONSUMER_NUM]; int consumer_ids[CONSUMER_NUM]; for (int i = 0; i < CONSUMER_NUM; i++) { consumer_ids[i] = i; pthread_create(&consumers[i], NULL, consumer, &consumer_ids[i]); } // 等待线程结束 for (int i = 0; i < PRODUCER_NUM; i++) { pthread_join(producers[i], NULL); } for (int i = 0; i < CONSUMER_NUM; i++) { pthread_join(consumers[i], NULL); } // 销毁信号量 sem_destroy(&empty); sem_destroy(&full); sem_destroy(&mutex); return 0; } 在这个代码中,生产者线程和消费者线程都会不断地生产和消费物品,直到达到指定数量。它们通过信号量来同步操作,当缓冲区为空时,消费者线程会等待信号量full,而生产者线程会等待信号量empty。当缓冲区达到满时,生产者线程会等待信号量full,而消费者线程会等待信号量empty。同时,它们还需要获取互斥量mutex来保证缓冲区的读写操作不会冲突。
以下是一个简单的生产者消费者问题的C语言代码: c #include <stdlib.h> #include <stdio.h> #include #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; // 缓冲区 int count = 0; // 缓冲区中的元素数量 int in = 0; // 缓冲区中下一个空槽位的索引 int out = 0; // 缓冲区中下一个可用元素的索引 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 互斥锁 pthread_cond_t full = PTHREAD_COND_INITIALIZER; // 缓冲区满条件变量 pthread_cond_t empty = PTHREAD_COND_INITIALIZER; // 缓冲区空条件变量 // 生产者线程函数 void* producer(void* arg) { while (1) { pthread_mutex_lock(&mutex); // 加锁 // 缓冲区已满,等待消费者消费后再生产 while (count == BUFFER_SIZE) { pthread_cond_wait(&empty, &mutex); } // 生产一个元素,并将其放入缓冲区 buffer[in] = rand(); printf("producer, in=%d, value=%d\n", in, buffer[in]); in = (in + 1) % BUFFER_SIZE; count++; pthread_cond_signal(&full); // 唤醒消费者 pthread_mutex_unlock(&mutex); // 解锁 } return NULL; } // 消费者线程函数 void* consumer(void* arg) { while (1) { pthread_mutex_lock(&mutex); // 加锁 // 缓冲区为空,等待生产者生产后再消费 while (count == 0) { pthread_cond_wait(&full, &mutex); } // 从缓冲区中取出一个元素并消费 int value = buffer[out]; printf("consumer, out=%d, value=%d\n", out, value); out = (out + 1) % BUFFER_SIZE; count--; pthread_cond_signal(&empty); // 唤醒生产者 pthread_mutex_unlock(&mutex); // 解锁 } return NULL; } int main() { pthread_t producer_thread, consumer_thread; // 创建生产者线程和消费者线程 if (pthread_create(&producer_thread, NULL, producer, NULL)) { perror("pthread_create"); exit(1); } if (pthread_create(&consumer_thread, NULL, consumer, NULL)) { perror("pthread_create"); exit(1); } // 等待两个线程结束 pthread_join(producer_thread, NULL); pthread_join(consumer_thread, NULL); return 0; } 这段代码实现了一个简单的生产者消费者问题,使用了互斥锁和条件变量来保证缓冲区的正确性。其中,生产者线程生产随机数并将其放入缓冲区,消费者线程从缓冲区中取出随机数并消费。如果缓冲区已满,生产者线程会等待信号,等待消费者线程消费后再进行生产;如果缓冲区为空,消费者线程会等待信号,等待生产者线程生产后再进行消费。
### 回答1: 以下是生产者消费者问题的C语言代码,使用PV操作实现同步和互斥: c #include <stdio.h> #include <stdlib.h> #include #include <semaphore.h> #define N 5 // 缓冲区大小 int buffer[N]; // 共享缓冲区 int in = 0; // 生产者放置产品的位置 int out = 0; // 消费者取产品的位置 sem_t empty; // 空缓冲区信号量 sem_t full; // 满缓冲区信号量 pthread_mutex_t mutex; // 互斥信号量 void *producer(void *arg) { int item; while (1) { item = rand() % 1000; // 生成随机数 sem_wait(&empty); // 等待空缓冲区 pthread_mutex_lock(&mutex); // 互斥访问缓冲区 buffer[in] = item; // 放置产品 printf("Producer puts item %d at position %d\n", item, in); in = (in + 1) % N; // 改变in指针位置 pthread_mutex_unlock(&mutex); // 释放互斥信号量 sem_post(&full); // 发送满缓冲区信号 } } void *consumer(void *arg) { int item; while (1) { sem_wait(&full); // 等待满缓冲区 pthread_mutex_lock(&mutex); // 互斥访问缓冲区 item = buffer[out]; // 取出产品 printf("Consumer gets item %d from position %d\n", item, out); out = (out + 1) % N; // 改变out指针位置 pthread_mutex_unlock(&mutex); // 释放互斥信号量 sem_post(&empty); // 发送空缓冲区信号 } } int main() { pthread_t tid_producer, tid_consumer; sem_init(&empty, 0, N); // 初始化空缓冲区信号量 sem_init(&full, 0, 0); // 初始化满缓冲区信号量 pthread_mutex_init(&mutex, NULL); // 初始化互斥信号量 pthread_create(&tid_producer, NULL, producer, NULL); // 创建生产者线程 pthread_create(&tid_consumer, NULL, consumer, NULL); // 创建消费者线程 pthread_join(tid_producer, NULL); pthread_join(tid_consumer, NULL); sem_destroy(&empty); // 销毁空缓冲区信号量 sem_destroy(&full); // 销毁满缓冲区信号量 pthread_mutex_destroy(&mutex); // 销毁互斥信号量 return 0; } 在上述代码中,使用了信号量和互斥锁来实现生产者和消费者之间的同步和互斥。其中,空缓冲区信号量 empty 初始值为 N,表示缓冲区初始为空;满缓冲区信号量 full 初始值为 0,表示缓冲区中没有产品。生产者线程在生产产品前等待空缓冲区信号量,如果缓冲区已满,则等待消费者线程取走产品;生产者线程放置产品前使用互斥锁保证只有一个线程可以访问缓冲区;放置完产品后,生产者线程发送满缓冲区信号量通知消费者线程。消费者线程在取产品前等待满缓冲区信号量,如果缓冲区为空,则等待生产者线程放置产品;消费者线程取出产品前使用互斥锁保证只有一个线程可以访问缓冲区;取出产品后,消费者线程发送空缓冲区信号量通知生产者线程。同时,使用互斥锁保证生产者和消费者线程互不干扰。 ### 回答2: 生产者消费者问题是指在多线程环境中,生产者线程负责生产数据,消费者线程负责消费数据,两者通过共享缓冲区来传递数据。为了保证生产者和消费者之间的正确性和同步,可以使用信号量的PV操作来实现。 在C语言中,可以使用信号量机制来实现生产者消费者问题。下面是一个简单的示例代码: c #include <stdio.h> #include <stdlib.h> #include #include <semaphore.h> #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; sem_t empty, full; int in = 0; int out = 0; void *producer(void *arg) { for (int i = 0; i < 100; i++) { sem_wait(&empty); // 等待缓冲区有空位 buffer[in] = i; in = (in + 1) % BUFFER_SIZE; sem_post(&full); // 通知缓冲区有数据 } return NULL; } void *consumer(void *arg) { int data; for (int i = 0; i < 100; i++) { sem_wait(&full); // 等待缓冲区有数据 data = buffer[out]; out = (out + 1) % BUFFER_SIZE; sem_post(&empty); // 通知缓冲区有空位 printf("Consumed: %d\n", data); } return NULL; } int main() { pthread_t producer_tid, consumer_tid; sem_init(&empty, 0, BUFFER_SIZE); sem_init(&full, 0, 0); pthread_create(&producer_tid, NULL, producer, NULL); pthread_create(&consumer_tid, NULL, consumer, NULL); pthread_join(producer_tid, NULL); pthread_join(consumer_tid, NULL); sem_destroy(&empty); sem_destroy(&full); return 0; } 以上代码中,使用了两个信号量empty和full分别表示缓冲区中的空位和有数据的数量。生产者线程使用sem_wait(&empty)等待缓冲区有空位,然后将数据写入缓冲区,并使用sem_post(&full)通知缓冲区有数据。消费者线程使用sem_wait(&full)等待缓冲区有数据,然后从缓冲区中读取数据,并使用sem_post(&empty)通知缓冲区有空位。 通过使用信号量的PV操作,可以实现生产者消费者之间的同步和正确性。 ### 回答3: 生产者消费者问题是一个经典的同步问题,在多线程或者多进程环境下,生产者线程生产数据,消费者线程消费数据。在这个问题中,需要确保生产和消费的线程之间的数据同步,避免生产者在空队列上进行生产,或者消费者在空队列上进行消费。 以下是一个基于C语言的生产者消费者问题的解决方案,使用了P操作和V操作来实现线程之间的同步: c //定义缓冲区大小 #define BUFFER_SIZE 10 int count = 0; //当前缓冲区中的数据个数 int buffer[BUFFER_SIZE]; //缓冲区 int in = 0; //指向下一个生产者存放数据的位置 int out = 0; //指向下一个消费者取出数据的位置 //生产者函数 void producer() { int item; while (true) { //生产数据 item = produce_item(); //等待缓冲区有空闲位置 while (count == BUFFER_SIZE) ; //空语句,等待缓冲区为空闲 //将生产好的数据放入缓冲区 buffer[in] = item; in = (in + 1) % BUFFER_SIZE; //增加数据个数 count++; //唤醒等待的消费者 if (count == 1) V(consumer_sem); } } //消费者函数 void consumer() { int item; while (true) { //等待缓冲区有数据 while (count == 0) ; //空语句,等待缓冲区有数据 //从缓冲区取出数据 item = buffer[out]; out = (out + 1) % BUFFER_SIZE; //减少数据个数 count--; //处理数据 consume_item(item); //唤醒等待的生产者 if (count == BUFFER_SIZE - 1) V(producer_sem); } } 在代码中,producer函数和consumer函数分别表示生产者和消费者的代码逻辑。在生产者函数中,会判断缓冲区是否有空闲位置,如果没有则等待;如果有空闲位置,则将生产的数据放入缓冲区,并增加数据个数,然后唤醒等待的消费者。在消费者函数中,会判断缓冲区是否有数据,如果没有则等待;如果有数据,则从缓冲区取出数据,减少数据个数,然后处理数据,并唤醒等待的生产者。 在代码中,使用了两个信号量producer_sem和consumer_sem来实现P操作和V操作。当一个线程在等待时,会调用P操作来等待,当一个线程完成执行后,会调用V操作来唤醒等待的线程。这样就能够保证生产者和消费者之间的数据同步与互斥。
下面是一个使用信号量实现进程同步与互斥的生产者消费者问题的 C 语言代码: c #include <stdio.h> #include <stdlib.h> #include #include <semaphore.h> #define BUFFER_SIZE 10 // 缓冲区大小 int buffer[BUFFER_SIZE]; // 缓冲区 int in = 0; // 缓冲区写指针 int out = 0; // 缓冲区读指针 sem_t empty; // 空缓冲区信号量 sem_t full; // 满缓冲区信号量 sem_t mutex; // 互斥信号量 void *producer(void *arg); void *consumer(void *arg); int main(int argc, char *argv[]) { pthread_t producer_thread, consumer_thread; // 初始化信号量 sem_init(&empty, 0, BUFFER_SIZE); sem_init(&full, 0, 0); sem_init(&mutex, 0, 1); // 创建生产者线程和消费者线程 pthread_create(&producer_thread, NULL, producer, NULL); pthread_create(&consumer_thread, NULL, consumer, NULL); // 等待线程结束 pthread_join(producer_thread, NULL); pthread_join(consumer_thread, NULL); // 销毁信号量 sem_destroy(&empty); sem_destroy(&full); sem_destroy(&mutex); return 0; } void *producer(void *arg) { int item; while (1) { item = rand() % 100; // 随机生成一个生产的产品 sem_wait(&empty); // 等待空缓冲区 sem_wait(&mutex); // 互斥访问缓冲区 buffer[in] = item; in = (in + 1) % BUFFER_SIZE; printf("Producer produced item %d\n", item); sem_post(&mutex); // 释放互斥信号量 sem_post(&full); // 发送满缓冲区信号量 } } void *consumer(void *arg) { int item; while (1) { sem_wait(&full); // 等待满缓冲区 sem_wait(&mutex); // 互斥访问缓冲区 item = buffer[out]; out = (out + 1) % BUFFER_SIZE; printf("Consumer consumed item %d\n", item); sem_post(&mutex); // 释放互斥信号量 sem_post(&empty); // 发送空缓冲区信号量 } } 上述代码中,我们使用了三个信号量 empty、full 和 mutex 分别表示空缓冲区、满缓冲区和互斥访问缓冲区的状态。生产者和消费者在访问缓冲区时,都需要先获取互斥信号量 mutex,以确保同一时刻只有一个进程在访问缓冲区。生产者在向缓冲区写入数据时,需要等待 empty 信号量,以确保缓冲区有空闲位置;写入完成后,需要释放 full 信号量,通知消费者缓冲区有数据可供消费。消费者在从缓冲区读取数据时,需要等待 full 信号量,以确保缓冲区有数据可供读取;读取完成后,需要释放 empty 信号量,通知生产者缓冲区有空闲位置。
以下是一个简单的生产者消费者问题的C语言实现代码: #include <stdio.h> #include <stdlib.h> #include #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; int count = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t producer_condition = PTHREAD_COND_INITIALIZER; pthread_cond_t consumer_condition = PTHREAD_COND_INITIALIZER; void *producer(void *arg) { int item; while (1) { item = rand() % 100; // 随机生成一个整数,模拟生产一个数据项 pthread_mutex_lock(&mutex); while (count == BUFFER_SIZE) { pthread_cond_wait(&producer_condition, &mutex); // 如果缓冲区已满,等待消费者取走数据 } buffer[count++] = item; printf("Producer produced %d\n", item); pthread_mutex_unlock(&mutex); pthread_cond_signal(&consumer_condition); // 通知一个消费者可以取走数据了 } } void *consumer(void *arg) { int item; while (1) { pthread_mutex_lock(&mutex); while (count == 0) { pthread_cond_wait(&consumer_condition, &mutex); // 如果缓冲区已空,等待生产者产生数据 } item = buffer[--count]; printf("Consumer consumed %d\n", item); pthread_mutex_unlock(&mutex); pthread_cond_signal(&producer_condition); // 通知一个生产者可以继续生产数据了 } } int main(int argc, char *argv[]) { pthread_t p, c; srand((unsigned int) time(NULL)); pthread_create(&p, NULL, producer, NULL); pthread_create(&c, NULL, consumer, NULL); pthread_join(p, NULL); pthread_join(c, NULL); return 0; } 这个代码使用了互斥锁和条件变量来实现线程间的同步与通信。生产者线程随机生成一个整数,将其放入缓冲区中,同时通知一个消费者线程可以取走数据;消费者线程从缓冲区中取走一个数据,同时通知一个生产者线程可以继续生产数据。这种方法可以避免竞争条件和死锁问题。

最新推荐

生产者——消费者 c语言

生产者——消费者 c语言 C语言 #include&lt;stdio.h&gt; #define size 5 int empty,full,in,out,a[size]={0},i,m=1; void produce() { int j; if(empty&gt;0) { empty--; a[in]=1; printf("生产一件产品,1为继续生产,2...

300126锐奇股份财务报告资产负债利润现金流量表企业治理结构股票交易研发创新等1391个指标(2007-2022).xlsx

包含1391个指标,其说明文档参考: https://blog.csdn.net/yushibing717/article/details/136115027 数据来源:基于上市公司公告数据整理 数据期间:从具体上市公司上市那一年开始-2022年度的数据,年度数据 包含各上市公司股票的、多年度的上市公司财务报表资产负债表、上市公司财务报表利润表、上市公司财务报表现金流量表间接法、直接法四表合在一个面板里面,方便比较和分析利用 含各个上市公司股票的、多年度的 偿债能力 披露财务指标 比率结构 经营能力 盈利能力 现金流量分析 风险水平 发展能力 每股指标 相对价值指标 股利分配 11类财务指标分析数据合在一个面板里面,方便比较和分析利用 含上市公司公告的公司治理、股权结构、审计、诉讼等数据 包含1391个指标,如: 股票简称 证券ID 注册具体地址 公司办公地址 办公地址邮政编码 董事会秘书 董秘联系电话 董秘传真 董秘电子邮箱 ..... 货币资金 其中:客户资金存款 结算备付金 其中:客户备付金 .........

【路径规划】基于matlab原子搜索算法栅格地图机器人最短路径规划【含Matlab源码 2887期】.mp4

CSDN佛怒唐莲上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

【语音隐写】基于matlab DCT扩频语音水印【含Matlab源码 466期】.mp4

CSDN佛怒唐莲上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

C#课程设计 扫雷游戏.zip

C#课程设计 扫雷游戏

DAC简介及参考电路PPT学习教案.pptx

DAC简介及参考电路PPT学习教案.pptx

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire

OceanBase数据库简介及原理解析

# 1. OceanBase数据库概述 ## 1.1 OceanBase数据库的发展历程 OceanBase数据库是由阿里巴巴集团自主研发的一款分布式关系型数据库系统,起源于阿里集团的业务需求和技术挑战。自2010年开始研发,经过多年的迭代和优化,OceanBase已经成为阿里巴巴集团重要的核心数据库产品之一。在实际的业务场景中,OceanBase已经被广泛应用于金融、电商、物流等各个领域。 ## 1.2 OceanBase数据库的特点和优势 OceanBase数据库具有以下特点和优势: - **分布式架构**:OceanBase采用多副本分布式架构,可以实现高可用和数据容灾。 -

python的pandas读取excel怎么将excel表里的列从1开始而不是0

在 Pandas 中,数据框的列默认从0开始编号,但我们可以通过自定义函数来进行数据列的转换。可以先将读取的数据框列的第一个值设为1,然后对后续列进行递增处理。 以下是示例代码: ```python import pandas as pd # 读取 Excel 文件 df = pd.read_excel('your_excel_file.xlsx') # 定义函数将列从1开始 def reset_column(x): return str(int(x) + 1) # 应用函数到所有列名 df = df.rename(columns=reset_column) # 打印数据框

第三章薪酬水平、薪酬系统的运行与控制.pptx

第三章薪酬水平、薪酬系统的运行与控制.pptx