linux c++ 集群管理进程怎么监控子进程
若以下回答无法解决问题,邀请你更新回答
1个回答
展开全部
Linux下一个进程在内存里有三部分的数据,就是”代码段”、”堆栈段”和”数据段”。接触过汇编语言的人了解,一般的CPU都有上述三种段寄存器,以方便操作系统的运行。这三个部分也是构成一个完整的执行序列的必要的部分。
“代码段”,顾名思义,就是存放了程序代码的数据,如果机器中有数个进程运行相同的一个程序,那么它们就可以使用相同的代码段。”堆栈段”存放的就是子程序的返回地址、子程序的参数以及程序的局部变量。而数据段则存放程序的全局变量,常数以及动态数据分配的数据空间(比如用malloc之类的函数取得的空间)。这其中有许多细节问题,这里限于篇幅就不多介绍了。系统如果同时运行数个相同的程序,它们之间就不能使用同一个堆栈段和数据段。
有两个基本的操作用于创建和修改进程:函数fork()用来创建一个新的进程,该进程几乎是当前进程的一个完全拷贝,利用了父进程的代码段、堆栈段、数据段,当父子进程中对共有的数据段进行重新设值或调用不同方法时,才会导致数据段及堆栈段的不同;函数族exec()用来启动另外的进程以取代当前运行的进程,除了PID仍是原来的值外,代码段、堆栈段、数据段已经完全被改写了。
引用自CNBlog
fork函数
#include <unistd.h>
pid_t fork(void);
当执行fork()函数后,会生成一个子进程,子进程的执行从fork()的返回值开始且代码继续往下执行。
所以fork()执行一次后会有两次返回值:第一次为原来的进程,即父进程会有一次返回值,表示新生成的子进程的进程ID;第二次为子进程的起始执行,返回值为0。
如果返回值为-1,则表示创建子进程失败,可能通过errno定位失败原因。
示例代码
以下代码演示了fork()创建一个子进程,及如何根据返回值区分主进程与子进程等。
123456789101112131415161718192021222324252627282930313233343536373839404142434445
#include <stdio.h>#include <stdlib.h>#include <unistd.h>int main (int argc, char ** argv) { int flag = 0; pid_t pId = fork(); if (pId == -1) { perror("fork error"); exit(EXIT_FAILURE); } else if (pId == 0) { int myPid = getpid(); int parentPid = getppid(); printf("Child:SelfID=%d ParentID=%d \n", myPid, parentPid); flag = 123; printf("Child:flag=%d %p \n", flag, &flag); int count = 0; do{ count ++; sleep(1); printf("Child count=%d \n", count); if (count >= 5) { break; } }while (1); return EXIT_SUCCESS; } else { printf("Parent:SelfID=%d MyChildPID=%d \n", getpid(), pId); flag = 456; printf("Parent:flag=%d %p \n", flag, &flag); // 连地址都一样,说明是真的完全拷贝,但值已经是不同的了.. int count = 0; do{ count ++; sleep(1); printf("Parent count=%d \n", count); if (count >= 2) { break; } }while (1); } return EXIT_SUCCESS;}
以上代码中,使用fork()创建了一个子进程。返回值pId有两个作用:一是判断fork()是否正常执行;二是判断fork()正常执行后如何区分父子进程。
在父子进程中,都各自打印出自己的进程ID及父/子进程ID。
通过flag的值可以验证创建的子进程是完全复制父进程的堆栈段(因为flag是在main()方法内声明的)的,两个进程都输出了flag=0的信息。接下来进程可以各自对flag再次更新值,做到了互不干扰。但从打印的int指针地址来看,指针地址值都是一样的,再次印证了子进程是对父进程的完全复制。
接下来,父进程只执行了两次打印,然后就结束且进程销毁退出了;但父进程的结束并不影响子进程的运行,子进程一直打印到数字5才正常退出。所以验证了fork()出来的进程是各自独立的,完全按照自己的代码逻辑运行直至执行完毕。
以下是运行效果截图。
“代码段”,顾名思义,就是存放了程序代码的数据,如果机器中有数个进程运行相同的一个程序,那么它们就可以使用相同的代码段。”堆栈段”存放的就是子程序的返回地址、子程序的参数以及程序的局部变量。而数据段则存放程序的全局变量,常数以及动态数据分配的数据空间(比如用malloc之类的函数取得的空间)。这其中有许多细节问题,这里限于篇幅就不多介绍了。系统如果同时运行数个相同的程序,它们之间就不能使用同一个堆栈段和数据段。
有两个基本的操作用于创建和修改进程:函数fork()用来创建一个新的进程,该进程几乎是当前进程的一个完全拷贝,利用了父进程的代码段、堆栈段、数据段,当父子进程中对共有的数据段进行重新设值或调用不同方法时,才会导致数据段及堆栈段的不同;函数族exec()用来启动另外的进程以取代当前运行的进程,除了PID仍是原来的值外,代码段、堆栈段、数据段已经完全被改写了。
引用自CNBlog
fork函数
#include <unistd.h>
pid_t fork(void);
当执行fork()函数后,会生成一个子进程,子进程的执行从fork()的返回值开始且代码继续往下执行。
所以fork()执行一次后会有两次返回值:第一次为原来的进程,即父进程会有一次返回值,表示新生成的子进程的进程ID;第二次为子进程的起始执行,返回值为0。
如果返回值为-1,则表示创建子进程失败,可能通过errno定位失败原因。
示例代码
以下代码演示了fork()创建一个子进程,及如何根据返回值区分主进程与子进程等。
123456789101112131415161718192021222324252627282930313233343536373839404142434445
#include <stdio.h>#include <stdlib.h>#include <unistd.h>int main (int argc, char ** argv) { int flag = 0; pid_t pId = fork(); if (pId == -1) { perror("fork error"); exit(EXIT_FAILURE); } else if (pId == 0) { int myPid = getpid(); int parentPid = getppid(); printf("Child:SelfID=%d ParentID=%d \n", myPid, parentPid); flag = 123; printf("Child:flag=%d %p \n", flag, &flag); int count = 0; do{ count ++; sleep(1); printf("Child count=%d \n", count); if (count >= 5) { break; } }while (1); return EXIT_SUCCESS; } else { printf("Parent:SelfID=%d MyChildPID=%d \n", getpid(), pId); flag = 456; printf("Parent:flag=%d %p \n", flag, &flag); // 连地址都一样,说明是真的完全拷贝,但值已经是不同的了.. int count = 0; do{ count ++; sleep(1); printf("Parent count=%d \n", count); if (count >= 2) { break; } }while (1); } return EXIT_SUCCESS;}
以上代码中,使用fork()创建了一个子进程。返回值pId有两个作用:一是判断fork()是否正常执行;二是判断fork()正常执行后如何区分父子进程。
在父子进程中,都各自打印出自己的进程ID及父/子进程ID。
通过flag的值可以验证创建的子进程是完全复制父进程的堆栈段(因为flag是在main()方法内声明的)的,两个进程都输出了flag=0的信息。接下来进程可以各自对flag再次更新值,做到了互不干扰。但从打印的int指针地址来看,指针地址值都是一样的,再次印证了子进程是对父进程的完全复制。
接下来,父进程只执行了两次打印,然后就结束且进程销毁退出了;但父进程的结束并不影响子进程的运行,子进程一直打印到数字5才正常退出。所以验证了fork()出来的进程是各自独立的,完全按照自己的代码逻辑运行直至执行完毕。
以下是运行效果截图。
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询
广告 您可能关注的内容 |