队列成员finished初始值为0,当父进程将全部200个整数全部放入队列后,将finished置为1,并等待10个子进程结束。 子进程依次不断地从队列中取出一个整数,并判断这个整数是不是素数,如果是素数,则输出这个进程的进程号以及这个整数。当然,每次从队列中取数之前,首先需要判断finished是否为1并且队列是否为空,如果是,则子进程结束。
时间: 2024-03-14 20:47:18 浏览: 37
STM32搭载FreeRTOS实现任务+消息队列+串口通信完整项目代码[实测]
好的,根据您的要求,我对之前的代码进行了修改,修改后的代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#define MAXSIZE 20
#define NUM_CHILDREN 10
struct queue_st {
int finished;
int head;
int tail;
char data[MAXSIZE];
int count;
};
void init_queue(struct queue_st *q) {
q->finished = 0;
q->head = 0;
q->tail = 0;
memset(q->data, 0, MAXSIZE);
q->count = 0;
}
int is_queue_empty(struct queue_st *q) {
return q->head == q->tail && q->count == 0;
}
int is_queue_full(struct queue_st *q) {
return q->head == q->tail && q->count > 0;
}
void enqueue(struct queue_st *q, char n) {
while (is_queue_full(q)) {
usleep(1000);
}
q->data[q->tail] = n;
q->tail = (q->tail + 1) % MAXSIZE;
q->count++;
}
char dequeue(struct queue_st *q) {
while (is_queue_empty(q) && !q->finished) {
usleep(1000);
}
if (is_queue_empty(q) && q->finished) {
return -1;
}
char n = q->data[q->head];
q->head = (q->head + 1) % MAXSIZE;
q->count--;
return n;
}
int is_prime(int n) {
if (n <= 1) {
return 0;
}
int i;
for (i = 2; i * i <= n; i++) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
void child_process(struct queue_st *q, int id) {
while (1) {
char n = dequeue(q);
if (n == -1) {
break;
}
if (is_prime(n)) {
printf("Process %d found prime: %d\n", id, n);
}
}
}
void parent_process(struct queue_st *q) {
int i;
for (i = 30000000; i < 30000200; i++) {
enqueue(q, i);
}
q->finished = 1;
for (i = 0; i < NUM_CHILDREN; i++) {
enqueue(q, -1);
}
for (i = 0; i < NUM_CHILDREN; i++) {
wait(NULL);
}
}
int main() {
struct queue_st q;
init_queue(&q);
int i;
for (i = 0; i < NUM_CHILDREN; i++) {
pid_t pid = fork();
if (pid == 0) {
child_process(&q, i);
exit(0);
}
}
parent_process(&q);
return 0;
}
```
修改后的程序在从队列中取数时,会先判断finished是否为1并且队列是否为空,如果是,则子进程结束。同时,在enqueue和dequeue函数中,增加了对队列为空或队列已满的判断,防止死锁。
阅读全文