编写一个程序primer_pro3.c,程序运行开始时,创建10个子进程和一个包含20个元素的队列,父进程首先创建一块共享存储器,将其附接在自己的地址空间中,将队列数据结构定义于其中,不断地依次将30000000到30000200之间这200个数放入队列,子进程依次不断地从队列中取出一个整数,并判断这个整数是不是素数,如果是素数,则输出这个进程的进程号以及这个整数。
时间: 2024-03-16 10:42:40 浏览: 191
下面是程序的实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <pthread.h>
#define MAXSIZE 20
struct queue_st {
int finished;
int head;
int tail;
int data[MAXSIZE];
int count;
};
int is_prime(int n) {
if (n < 2) {
return 0;
}
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
void *worker(void *arg) {
struct queue_st *queue = (struct queue_st *) arg;
int pid = getpid();
while (1) {
while (queue->count == 0) {
if (queue->finished) {
return NULL;
}
usleep(1000);
}
int n = queue->data[queue->head];
queue->head = (queue->head + 1) % MAXSIZE;
queue->count--;
if (is_prime(n)) {
printf("pid=%d, prime=%d\n", pid, n);
}
}
}
int main() {
int shmid = shmget(IPC_PRIVATE, sizeof(struct queue_st), IPC_CREAT | 0666);
if (shmid < 0) {
perror("shmget");
exit(EXIT_FAILURE);
}
struct queue_st *queue = (struct queue_st *) shmat(shmid, NULL, 0);
if (queue == (void *) -1) {
perror("shmat");
exit(EXIT_FAILURE);
}
queue->finished = 0;
queue->head = 0;
queue->tail = 0;
queue->count = 0;
pid_t pid;
for (int i = 0; i < 10; i++) {
pid = fork();
if (pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
} else if (pid == 0) {
worker(queue);
exit(EXIT_SUCCESS);
}
}
for (int i = 30000000; i <= 30000200; i++) {
while (queue->count == MAXSIZE) {
usleep(1000);
}
queue->data[queue->tail] = i;
queue->tail = (queue->tail + 1) % MAXSIZE;
queue->count++;
}
queue->finished = 1;
for (int i = 0; i < 10; i++) {
wait(NULL);
}
shmdt(queue);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
```
程序首先创建了一块共享内存,将队列数据结构定义于其中,并初始化队列为空。然后创建了10个子进程,并启动每个子进程执行worker函数。worker函数不断地从队列中取出一个整数,并判断是否为素数,如果是素数,则输出进程号和这个整数。父进程将30000000到30000200之间的200个数依次放入队列中,如果队列满,则等待。当父进程将所有数据放入队列后,将队列的finished成员设为1,表示所有数据已放入队列中。然后等待所有子进程结束,并回收子进程的资源。最后将共享内存断开并删除。
阅读全文