在 C 中分叉 - 无限循环?
Forking within C - infinite loop?
正在尝试学习 C 分支。它正确地打印出主循环假设 运行 的次数和正确的线程数,但执行时间已关闭并且程序永远不会终止。我是否正在制作无限数量的流程?
经过一些建议,这里是一个更清晰的代码版本。旧版本位于下方。更新的部分仍在创建许多子进程并且永远不会退出。我只是看不出出了什么问题。
更新:John Hascall 的建议修复了格式和线程 运行ning 乱序。仍然会生成无限数量的线程,但现在顺序正确。即打印线程执行时间 1、2、3、4...等。不要认为问题是 wait 系统调用,而是去研究它,看看我是否找不到任何东西。
更新**:我找到了解决方案。我认为第一个问题是我没有等待命令,第二个是在等待时我不小心删除了对 count < argv[1] 的检查。我把它放回去,它似乎 运行ning 正确!感谢大家的帮助和风格指导!工作版本如下。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "./processes.h"
int main(int argc, char** argv) {
if (argc != 4) {
printf("Wrong number of arguments entered. Usage: #processes sleepTime inputFile.\n");
return 1;
}
if(atoi(argv[1]) <= 0){
printf("Incorrect number of children, must be greater than 0");
return -1;
}
int count = 0;
int index;
Child *child = malloc(sizeof(Child) * atoi(argv[1]));
int childIndex;
int pid;
do{
switch (pid = fork()){
case -1:
printf("Fork failed\n");
exit(1);
case 0:
sleep(atoi(argv[2]) * childIndex);
gettimeofday(&child[childIndex].endTime, NULL);
double elapsed = child[childIndex].endTime.tv_usec - child[childIndex].startTime.tv_usec;
printf("Time for process %d = %f microseconds\n", childIndex, elapsed);
break;
default:
childIndex = count + 1;
gettimeofday(&child[count].startTime, NULL);
child[count].index = count + 1;
child[count].pid = pid;
count++;
}
} while((wait(NULL) != -1) && (count < atoi(argv[1])));
return 1;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "./processes.h"
int main(int argc, char** argv) {
if (argc != 4) {
printf("Wrong number of arguments entered. Try again.");
return 1;
}
if(atoi(argv[1]) <= 0){
printf("Incorrect number of children, must be greater than 0");
return -1;
}
int count;
int index;
Child *child = malloc(sizeof(Child) * atoi(argv[1]));
int pid = 1;
int childIndex;
for (count = 0; count < atoi(argv[1]); count++) {
if (pid != 0) {
childIndex = count + 1;
gettimeofday(&child[count].startTime, NULL);
child[count].index = count + 1;
pid = fork();
if (pid != 0){
child[count].pid = pid;
printf("Main thread loop: %d\n", count);
printf("Child process: %d\n", getpid());
}
}
}
if (pid == 0) {
//this is the child process
sleep(atoi(argv[2]) * childIndex);
gettimeofday(&child[childIndex].endTime, NULL);
double elapsed = child[childIndex].endTime.tv_usec - child[childIndex].startTime.tv_usec;
printf("Time for process %d = %f microseconds\n", childIndex, elapsed);
//printf("This is thread %d reporting in.\n", childIndex);
}
// printf("Testing\n");
return 1;
}
最大的问题是您的 child 代码:
if (pid == 0) {
....
}
属于 parent 代码的同一个循环(紧接着说):
if (pid != 0) {
....
}
此外,您从不检查 pid == -1
(fork()
失败)。
更标准的写法是:
switch (pid = fork()) {
case -1:
/* handle fork error */
exit(1);
case 0:
/* child code goes here */
_exit(0);
default:
/* parent code goes here */
}
/* Also you probably want to look into the `wait()` syscall. */
do {} while (wait(NULL) != -1); /* <--- the very minimum */
正在尝试学习 C 分支。它正确地打印出主循环假设 运行 的次数和正确的线程数,但执行时间已关闭并且程序永远不会终止。我是否正在制作无限数量的流程?
经过一些建议,这里是一个更清晰的代码版本。旧版本位于下方。更新的部分仍在创建许多子进程并且永远不会退出。我只是看不出出了什么问题。
更新:John Hascall 的建议修复了格式和线程 运行ning 乱序。仍然会生成无限数量的线程,但现在顺序正确。即打印线程执行时间 1、2、3、4...等。不要认为问题是 wait 系统调用,而是去研究它,看看我是否找不到任何东西。
更新**:我找到了解决方案。我认为第一个问题是我没有等待命令,第二个是在等待时我不小心删除了对 count < argv[1] 的检查。我把它放回去,它似乎 运行ning 正确!感谢大家的帮助和风格指导!工作版本如下。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "./processes.h"
int main(int argc, char** argv) {
if (argc != 4) {
printf("Wrong number of arguments entered. Usage: #processes sleepTime inputFile.\n");
return 1;
}
if(atoi(argv[1]) <= 0){
printf("Incorrect number of children, must be greater than 0");
return -1;
}
int count = 0;
int index;
Child *child = malloc(sizeof(Child) * atoi(argv[1]));
int childIndex;
int pid;
do{
switch (pid = fork()){
case -1:
printf("Fork failed\n");
exit(1);
case 0:
sleep(atoi(argv[2]) * childIndex);
gettimeofday(&child[childIndex].endTime, NULL);
double elapsed = child[childIndex].endTime.tv_usec - child[childIndex].startTime.tv_usec;
printf("Time for process %d = %f microseconds\n", childIndex, elapsed);
break;
default:
childIndex = count + 1;
gettimeofday(&child[count].startTime, NULL);
child[count].index = count + 1;
child[count].pid = pid;
count++;
}
} while((wait(NULL) != -1) && (count < atoi(argv[1])));
return 1;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "./processes.h"
int main(int argc, char** argv) {
if (argc != 4) {
printf("Wrong number of arguments entered. Try again.");
return 1;
}
if(atoi(argv[1]) <= 0){
printf("Incorrect number of children, must be greater than 0");
return -1;
}
int count;
int index;
Child *child = malloc(sizeof(Child) * atoi(argv[1]));
int pid = 1;
int childIndex;
for (count = 0; count < atoi(argv[1]); count++) {
if (pid != 0) {
childIndex = count + 1;
gettimeofday(&child[count].startTime, NULL);
child[count].index = count + 1;
pid = fork();
if (pid != 0){
child[count].pid = pid;
printf("Main thread loop: %d\n", count);
printf("Child process: %d\n", getpid());
}
}
}
if (pid == 0) {
//this is the child process
sleep(atoi(argv[2]) * childIndex);
gettimeofday(&child[childIndex].endTime, NULL);
double elapsed = child[childIndex].endTime.tv_usec - child[childIndex].startTime.tv_usec;
printf("Time for process %d = %f microseconds\n", childIndex, elapsed);
//printf("This is thread %d reporting in.\n", childIndex);
}
// printf("Testing\n");
return 1;
}
最大的问题是您的 child 代码:
if (pid == 0) {
....
}
属于 parent 代码的同一个循环(紧接着说):
if (pid != 0) {
....
}
此外,您从不检查 pid == -1
(fork()
失败)。
更标准的写法是:
switch (pid = fork()) {
case -1:
/* handle fork error */
exit(1);
case 0:
/* child code goes here */
_exit(0);
default:
/* parent code goes here */
}
/* Also you probably want to look into the `wait()` syscall. */
do {} while (wait(NULL) != -1); /* <--- the very minimum */