我被要求将生产者(客户端)开发给生产者(服务器),生产者创建流程,等待消费者读取共享内存和删除流程,然后将控制权交还给生产者。杀死进程并关闭共享内存块。
我研究了睡眠和等待之间的区别,并意识到只要调用fork(),子进程就会开始运行。
以下代码是在创建流程之后检查它们是否是父流程。如果是,他们等待(0)。 *现在我的问题是,如何知道消费者中的代码开始执行的位置,以及如何将其传回去? *
else if(pid > 0)
{
wait(0);
}
下面可以看到生产者使用的主循环。
int noToCreate = atoi(argv[2]); // (user inputs on cmd line "./prod 20 10 5" - 20 size of shared mem, 10 process to be created, 5 processes to be deleted)
while(*memSig != 2)
{
while(*memSig == 1) // set memsignature to sleep while..
{
sleep(1);
}
for(B = 0; B < noToCreate; B++)
{
pid = fork();
if(pid == -1)
{
perror("Error forking");
exit(1);
}
else if(pid > 0)
{
wait(0);
}
else
{
srand(getpid());
while(x == 0)
{
if(*randNum == 101)
{
*randNum = rand() % (100 -
1) + 1;
*pidNum = getpid();
printf("priority: %d
Process ID: %d \n", *randNum, *pidNum);
x = 1;
}
else
{
*randNum++;
*pidNum++;
}
}
exit(0);
}
} /* Closes main for loop */
if(*memSig == 0)
{
*memSig = 1;
}
} /* Closes main while loop */
谢谢一群人:)
答案 0 :(得分:2)
wait
让父母被阻止,直到任何孩子结束。你可以使用waitpid
让父母等待特定的孩子。
当子进程结束时,它将设置信号SIG_CHILD
。
答案 1 :(得分:2)
fork之后的子进程的pid为零,因此您在调用srand函数时处于子进程中。
另一个pid是对于允许原始线程等待孩子完成的子进程。如果您希望在进程之间传递数据,请考虑使用管道。 popen调用返回两个文件描述符,一个用于写入结束,另一个用于读取结束。在fork之前设置它,并且两个进程可以通信。
答案 2 :(得分:1)
wait
让父母等待任何孩子在继续之前终止(最好使用waitpid
等待某个孩子),而sleep
让进程进入休眠状态并恢复它,一旦论证结束时间过了。
这两个调用都会使进程阻止
并且 NOT 表示孩子会立即跑,这是不确定的行为!
如果要在生产者和使用者之间传递数据,请使用管道或* NIX套接字,或者如果单个整数足够,则使用子进程中exit
的返回值。
请参阅man wait,您可以使用宏WEXITSTATUS
获取子项的返回值。
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int
main(int argc, char *argv[])
{
pid_t cpid, w;
int status;
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { /* Code executed by child */
printf("Child PID is %ld\n", (long) getpid());
if (argc == 1)
pause(); /* Wait for signals */
_exit(atoi(argv[1]));
} else { /* Code executed by parent */
do {
w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
if (w == -1) {
perror("waitpid");
exit(EXIT_FAILURE);
}
if (WIFEXITED(status)) {
printf("exited, status=%d\n", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
printf("killed by signal %d\n", WTERMSIG(status));
} else if (WIFSTOPPED(status)) {
printf("stopped by signal %d\n", WSTOPSIG(status));
} else if (WIFCONTINUED(status)) {
printf("continued\n");
}
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
exit(EXIT_SUCCESS);
}
}