每个应用程序(程序)都是通过过程来执行的,过程是程序的运行实例。进程是通过不同的系统调用创建的,最受欢迎的是fork()和exec()
叉()
pid_t pid = fork();
fork()通过复制调用过程来创建一个新过程,该新过程称为子进程,是与父进程完全相同的调用进程,称为父进程,但以下各项除外:
- 该子项具有其自己的唯一进程ID,并且此PID与任何现有进程组的ID不匹配。
- 子级的父进程ID与父级的进程ID相同。
- 子级不会继承其父级的内存锁和信号量调整。
- 子级不会从其父级继承未完成的异步I / O操作,也不会从其父级继承任何异步I / O上下文。
返回fork()的值
成功后,将在父级中返回子进程的PID,并在子级中返回0。失败时,将在父级中返回-1,不创建任何子级进程,并正确设置errno。
有关fork系统调用的详细文章
exec()
exec()系列函数将当前过程映像替换为新的过程映像。它将程序加载到当前进程空间中,并从入口点运行它。
exec()系列由以下函数组成,我已经在以下C程序中实现了execv() ,您可以尝试通过练习来休息一下
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,
char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],
char *const envp[]);
前叉vs执行
- fork启动一个新进程,该进程是调用它的进程的副本,而exec用另一个(不同的)进程映像替换当前进程映像。
- 在fork()的情况下,父进程和子进程都同时执行,而Control绝不会返回到原始程序,除非出现exec()错误。
// C program to illustrate use of fork() &
// exec() system call for process creation
#include
#include
#include
#include
#include
#include
int main(){
pid_t pid;
int ret = 1;
int status;
pid = fork();
if (pid == -1){
// pid == -1 means error occured
printf("can't fork, error occured\n");
exit(EXIT_FAILURE);
}
else if (pid == 0){
// pid == 0 means child process created
// getpid() returns process id of calling process
// Here It will return process id of child process
printf("child process, pid = %u\n",getpid());
// Here It will return Parent of child Process means Parent process it self
printf("parent of child process, pid = %u\n",getppid());
// the argv list first argument should point to
// filename associated with file being executed
// the array pointer must be terminated by NULL
// pointer
char * argv_list[] = {"ls","-lart","/home",NULL};
// the execv() only return if error occured.
// The return value is -1
execv("ls",argv_list);
exit(0);
}
else{
// a positive number is returned for the pid of
// parent process
// getppid() returns process id of parent of
// calling process
// Here It will return parent of parent process's ID
printf("Parent Of parent process, pid = %u\n",getppid());
printf("parent process, pid = %u\n",getpid());
// the parent process calls waitpid() on the child
// waitpid() system call suspends execution of
// calling process until a child specified by pid
// argument has changed state
// see wait() man page for all the flags or options
// used here
if (waitpid(pid, &status, 0) > 0) {
if (WIFEXITED(status) && !WEXITSTATUS(status))
printf("program execution successful\n");
else if (WIFEXITED(status) && WEXITSTATUS(status)) {
if (WEXITSTATUS(status) == 127) {
// execv failed
printf("execv failed\n");
}
else
printf("program terminated normally,"
" but returned a non-zero status\n");
}
else
printf("program didn't terminate normally\n");
}
else {
// waitpid() failed
printf("waitpid() failed\n");
}
exit(0);
}
return 0;
}
输出:
parent process, pid = 11523
child process, pid = 14188
Program execution successful
参考 :
Linux手册页
想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。