【发布时间】:2021-10-19 03:58:42
【问题描述】:
作为我的任务的一部分,我必须实现子父进程。
“父进程不应等待子进程退出,而是应在元素到达共享缓冲区后立即打印元素”。
我知道父母必须等待孩子结束的情况,但是如何以异步方式实现从孩子到父母的消息通信?
附:确切的 Q 是
编写一个程序,其主例程从用户那里获得两个参数 n 和 d,即在从 shell 调用时传递给您的程序。然后,您的程序将创建一个共享内存和一个子进程。 子进程应该获取 n 和 d 的值(您有多种选择)并创建一个长度为 n 的等差数列,其第一个元素为 0,每个后续元素的值为 kd,其中 k 是元素编号(k= 0 到 n-1)。 子进程应一次创建一个元素,并在生成序列的元素之间等待一个随机的时间间隔(0 到 9.999 秒)。一旦生成了一个元素,孩子就会按照第 4 课的幻灯片 33-37 中的描述将元素组织到共享缓冲区中。 (例如:如果 n=5 和 d=2,则序列应为 0,2,4,6,8) 父进程不应等待子进程退出,而是应在元素到达共享缓冲区后立即打印元素(再次,以类似于第 4 课的幻灯片 33-37 的方式) 暗示;使用 fflush() 确保 printf 立即打印到屏幕上。
到目前为止我的代码 - gist
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
void printLab4(int n, int a, int *fibo)
{
int i;
for (i = 0; i < n; i++)
printf("%d -> %d\n", i, fibo[i]);
}
void computeLab4(int n, int a, int *fibo)
{
int i;
for (i = 0; i < n; i++)
{
int sleepSec = rand() % 10;
printf("sleeping for %d : ", sleepSec);
sleep(sleepSec);
fibo[i] = i * a;
// randomly sleeping for 0-10 secs
printf("Generated new element %d after %d seconds \n", fibo[i], sleepSec);
}
}
int main(int argc, char *argv[])
{
pid_t childPID;
int status;
int shm_fd;
int *shared_memory;
int msize; // the size (in bytes) of the shared memory segment
const char *name = "Lab_4";
int n, a;
if (argc != 3)
{
fprintf(stderr, "usage: %s <Lab4 Seq to be generated>\n", argv[0]);
return -1;
}
n = atoi(argv[1]);
a = atoi(argv[2]);
printf("%d \n", n);
printf("%d \n", a);
if (n < 0 || a < 0)
{
fprintf(stderr, "Illegal number: %s\n", argv[1]);
return -2;
}
// calculating the array size based on the number of terms being passed from child to parent
msize = (n + 2) * sizeof(int);
// open the memory
shm_fd = shm_open(name, O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG);
if (shm_fd < 0)
{
fprintf(stderr, "Error in shm_open()");
return -3;
}
printf("Created shared memory object %s\n", name);
// attach the shared memory segment
ftruncate(shm_fd, msize);
printf("shmat returned\n");
// allocating the shared memory
shared_memory = (int *)mmap(NULL, msize, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (shared_memory == NULL)
{
fprintf(stderr, "Error in mmap()");
return -3;
}
printf("Shared memory segment allocated correctly (%d bytes).\n", msize);
shared_memory[0] = n;
shared_memory[1] = a;
childPID = fork();
if (childPID == -1)
{
fprintf(stderr, "Cannot proceed. fork() error");
return -4;
}
if (childPID == 0)
{
// then we're the child process
computeLab4(shared_memory[0], shared_memory[1], shared_memory + 1);
exit(0);
}
else
{
// parent will wait until the child finished
wait(&status);
// print the final results in the
printLab4(shared_memory[0], shared_memory[1], shared_memory + 1);
// now detach the shared memory segment
shm_unlink(name);
}
return 0;
}
【问题讨论】:
-
没有代码很难帮你。你有共享缓冲区的代码吗?有很多方法可以做到这一点,如果不理解“共享缓冲区”的分配意味着什么,我们很可能会把你引向正确的方向。
-
我不确定这可以通过 100 种不同的方式完成,但它接近 100 种。需要更多详细信息。否则,它太宽泛,无法得到答案。
-
在问题中发布您的代码——而不是在 GitHub gist 等临时存储位置。
-
您的代码会休眠整秒。指定范围 0 到 9.999 秒的含义是您的孩子应该睡小数秒。您可能应该重新考虑您正在使用哪个睡眠功能。