(3) 实现进程池计算素数:编写一个程序primer_pro3.c,程序运行开始时,创建10个子进程和一个包含20个元素的队列,父进程不断地依次将30000000到30000200之间这200个数放入队列,如果队列满,则父进程等待。 队列的定义可参考如下: #define MAXSIZE 20 struct quequ_st{ int finished; //父进程是否已将所有200个整数放入了队列 int head; //队列头
时间: 2024-03-12 09:45:14 浏览: 103
以下是primer_pro3.c的代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <pthread.h>
#include <semaphore.h>
#define MAXSIZE 20
// 定义队列结构体
typedef struct queue_st {
int finished; // 父进程是否将所有200个整数放入队列
int head; // 队列头
int tail; // 队列尾
int data[MAXSIZE]; // 队列数据
} queue_t;
// 定义信号量
sem_t empty;
sem_t full;
sem_t mutex;
// 定义全局变量
int prime_count = 0;
// 判断是否为质数
bool is_prime(int num) {
if (num <= 1) {
return false;
}
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
// 计算素数
void *calculate_prime(void *arg) {
int num;
queue_t *queue = (queue_t *)arg;
while (true) {
sem_wait(&full); // 如果队列为空,等待
sem_wait(&mutex); // 获取互斥锁
num = queue->data[queue->head]; // 从队列头取出一个数
queue->head = (queue->head + 1) % MAXSIZE; // 更新队列头
sem_post(&mutex); // 释放互斥锁
sem_post(&empty); // 增加一个空闲位置
if (num == -1) { // 如果取出的数为-1,说明已经没有数可以处理了
break;
}
if (is_prime(num)) { // 如果是质数,累计计数
prime_count++;
}
}
pthread_exit(NULL);
}
int main() {
pid_t pid;
int num = 30000000;
queue_t queue = {0, 0, 0, {0}}; // 初始化队列
// 初始化信号量
sem_init(&empty, 0, MAXSIZE);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
// 创建10个子进程
for (int i = 0; i < 10; i++) {
pid = fork();
if (pid == 0) { // 子进程
calculate_prime(&queue);
exit(0);
}
}
// 父进程循环放入200个数
for (int i = 0; i < 200; i++) {
sem_wait(&empty); // 如果队列已满,等待
sem_wait(&mutex); // 获取互斥锁
queue.data[queue.tail] = num; // 放入一个数
queue.tail = (queue.tail + 1) % MAXSIZE; // 更新队列尾
num++;
sem_post(&mutex); // 释放互斥锁
sem_post(&full); // 增加一个已有数据的位置
}
// 父进程等待子进程处理完毕
for (int i = 0; i < 10; i++) {
sem_wait(&empty);
sem_wait(&mutex);
queue.data[queue.tail] = -1; // 放入一个-1,表示没有数据可以处理了
queue.tail = (queue.tail + 1) % MAXSIZE;
sem_post(&mutex);
sem_post(&full);
}
// 父进程等待子进程退出
for (int i = 0; i < 10; i++) {
wait(NULL);
}
printf("Total prime count: %d\n", prime_count);
sem_destroy(&empty);
sem_destroy(&full);
sem_destroy(&mutex);
return 0;
}
```
程序运行时,父进程创建10个子进程,每个子进程从队列头取出一个数,判断是否为质数,如果是质数则累计计数,如果取出的数为-1,则说明已经没有数可以处理了,子进程退出。父进程循环放入200个数,如果队列已满,则等待。放入完毕后,父进程再往队列里放入10个-1,表示没有数据可以处理了。最后父进程等待子进程退出,输出计数结果。
阅读全文