我有以下代码,它使用fork()
:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#define NUM_THREADS 4
int main()
{
int i;
pid_t pid;
for(i = 0; i < NUM_THREADS; i++){ //Do this equal to the number of threads
pid = fork();//Use this to avoid multiple forking
if(pid == 0){ //If it's a child process
printf("Hello World! Greetings from PID: %ld! :D\n", (long)getpid()); //getpid returns the pid of the process
exit(0); //Exit the process
}else if(pid == -1){
printf("Oh no! Could not fork! :( Exiting!\n");
return 0;
}
}
int status;
for(i = 0; i < NUM_THREADS; i++){
wait(&status);//wait until all the children processes have finished.
}
printf("All done! I am the parent process! My PID is: %ld if you were curious! \n", (long)getpid());
return 0;
}
这是作为一个例子提供给我们的。 它的输出如下:
Hello World!来自PID的问候:118358! :d
你好,世界!来自PID的问候:118359! :d
你好,世界!来自PID的问候:118360! :d
你好,世界!来自PID的问候:118362! :d
我想要做的是,让父进程创建一个子进程,而不是让父进程有多个子进程,以创建一个子进程,依此类推定义的线程数。我怎么能这样做?
答案 0 :(得分:3)
您的示例代码使用fork()
的返回值来区分父级和子级。它继续在父级中迭代(假设fork()
没有报告错误),并且exit()
在子级中没有迭代(在发出一些输出之后)。这是完全常规的。
你打算做的事情并没有太大的不同;你所描述的主要是交换父母和孩子的角色。实际上,你的工作比较简单,因为每个父母只需要wait()
一个孩子。它可以在循环内部或外部执行此操作,前提是仅在最后一个子wait()
s时,它应该预期该调用指示由于该子级没有自己的子级而导致的错误。但是,如果父级不是来自循环内部的exit()
或return
,那么它确实需要突破而不是进一步迭代。
答案 1 :(得分:2)
此任务与将迭代解决方案转换为递归解决方案相同。第一步是删除for
循环。然后修改子代码以便每个子代:
关键是每个孩子都会获得其父变量的副本,因此如果孩子更新计数变量,然后分叉,新孩子将看到更新的计数。
答案 2 :(得分:1)
首先,术语&#34;线程&#34;你在这种情况下使用是不合适的。 分叉意味着&#34;创建过程&#34;不是&#34;线程&#34;。
您可以使用递归解决方案,但您必须记住创建进程的每个进程都应该等待返回状态以避免Zombie Process。如果不在进程之间使用任何共享变量,则可以使用单个变量计数器,该计数器在每次分叉时都会递增。但是一旦计数器变量达到最大值,最小的&#34;最年轻的&#34;进程,我的意思是创建的最后一个进程应该退出,并且一个接一个的进程将退出。
这是一个很好的简单代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define NUM_PROCESS 5
int counter = 0;
void child_func()
{
pid_t pid;
if (counter < NUM_PROCESS) {
counter++;
pid = fork();
if (pid < 0) {
printf("fork failed counter = %d\n", counter);
}
else if (pid == 0) {
printf("Hello world ! Greetings from pid %ld\n", (long)getpid());
if (counter == NUM_PROCESS) {
exit(0);
}
else {
child_func();
}
}
else {
long var = pid;
wait(&pid);
printf("My pid is %ld and i am the parent of %ld child, i exit\n", (long)getpid(), var);
exit(0);
}
}
}
int main(void)
{
pid_t pid;
pid = fork();
if (pid < 0) {
printf("Fork failed %d\n", counter);
return -1;
}
if (pid == 0) {
child_func();
}
else {
wait(&pid);
}
return 0;
}