(3) 实现进程池计算素数:编写一个程序primer_pro3.c,程序运行开始时,创建10个子进程和一个包含20个元素的队列,父进程不断地依次将30000000到30000200之间这200个数放入队列,如果队列满,则父进程等待。 队列的定义可参考如下: #define MAXSIZE 20 struct quequ_st{ int finished; //父进程是否已将所有200个整数放入了队列 int head; //队列头 int tail; //队列尾 char data[MAXSIZE]; //队列数据 int count; //当前队列中数据个数 }; 队列成员finished初始值为0,当父进程将全部200个整数全部放入队列后,将finished置为1,并等待10个子进程结束。 子进程依次不断地从队列中取出一个整数,并判断这个整数是不是素数,如果是素数,则输出这个进程的进程号以及这个整数。当然,每次从队列中取数之前,首先需要判断finished是否为1并且队列是否为空,如果是,则子进程结束。
时间: 2024-03-14 10:45:39 浏览: 65
利用进程实现求解素数
下面是实现进程池计算素数的程序primer_pro3.c:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <pthread.h>
#include <string.h>
#include <math.h>
#define MAXSIZE 20
struct queue_st {
int finished; //父进程是否已将所有200个整数放入了队列
int head; //队列头
int tail; //队列尾
int data[MAXSIZE]; //队列数据
int count; //当前队列中数据个数
};
struct queue_st queue = {0, 0, 0, {0}, 0};
void* prime(void* arg);
int main() {
pid_t pid;
int i, num;
pthread_t tid;
//创建子进程
for (i = 0; i < 10; i++) {
pid = fork();
if (pid < 0) {
perror("fork error");
exit(1);
} else if (pid == 0) {
//子进程
pthread_create(&tid, NULL, prime, NULL);
pthread_join(tid, NULL);
exit(0);
}
}
//父进程
for (num = 30000000; num < 30000200; num++) {
while (queue.count == MAXSIZE) {
//队列满,等待
usleep(100000);
}
queue.data[queue.tail] = num;
queue.tail = (queue.tail + 1) % MAXSIZE;
queue.count++;
if (queue.count == MAXSIZE) {
//队列满,通知子进程
kill(0, SIGUSR1);
}
}
queue.finished = 1;
//等待子进程结束
for (i = 0; i < 10; i++) {
wait(NULL);
}
return 0;
}
void* prime(void* arg) {
int num, i, is_prime;
while (1) {
//判断队列是否为空
while (queue.count == 0) {
if (queue.finished) {
//父进程已将所有数放入队列,退出
pthread_exit(NULL);
}
//等待父进程放入数
pause();
}
num = queue.data[queue.head];
queue.head = (queue.head + 1) % MAXSIZE;
queue.count--;
is_prime = 1;
for (i = 2; i <= sqrt(num); i++) {
if (num % i == 0) {
is_prime = 0;
break;
}
}
if (is_prime) {
printf("pid=%d, num=%d\n", getpid(), num);
}
}
}
```
程序首先创建10个子进程,并且每个子进程都调用prime函数来处理队列中的数据。当父进程将一个数放入队列时,如果队列已满,则父进程等待。如果队列满了,父进程会发送一个SIGUSR1信号给所有子进程,以通知它们队列已经满了。每个子进程都通过调用pause函数来等待父进程的通知。当一个子进程从队列中取出一个数后,它会判断这个数是否为素数,如果是,则输出进程号以及这个整数。如果队列为空,子进程会等待父进程放入数据。如果父进程已经将所有数据放入队列,那么子进程就退出。最后,父进程等待所有子进程结束后,程序才结束。
阅读全文