c语言之进程函数
1. 进程创建
#include <sys/types.h>#include <unistd.h>pid_t fork(void);
fork 创建一个新进程
fork() creates a new process by duplicating the calling process. The new process is referred to as the child process. The calling process is referred to as the parent process.
fork()
通过复制调用进程来创建一个新进程。新创建的进程称为子进程,而调用进程称为父进程。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>int main() {pid_t pid = fork();if (pid == 0) {/*在父进程中,子进程的pid==0getpid() 获取进程id*/printf("子进程 PID: %d\n", getpid());} else {// 父进程pid 大于0printf("父进程 PID: %d\n", getpid());}return 0;
}
The child process and the parent process run in separate memory spaces. At
the time of fork() both memory spaces have the same content. Memory writes,
file mappings (mmap(2)), and unmappings (munmap(2)) performed by one of the
processes do not affect the other.
子进程和父进程运行在独立的内存空间中。调用fork()
时,两者的内存空间内容完全一致。任一进程对内存的写入、文件映射(mmap(2)
)或解除映射(munmap(2)
)操作均不会影响另一进程。
#include <unistd.h>
#include <stdio.h>int main() {int val = 10;pid_t pid = fork();if (pid == 0) {val = 20; // 子进程修改不影响父进程printf("Child val: %d\n", val);} else {printf("Parent val: %d\n", val); // 输出仍为10}return 0;
}
2. 僵尸进程
僵尸进程(Zombie Process)是指已经完成执行(通过exit()
系统调用终止)但其退出状态尚未被父进程读取(通过wait()
或waitpid()
系统调用)的进程。
产生原因:父进程还存在,但是去做的别的事情了(比如在一个死循环,没有退出),此时子进程退出之后,就变成了僵尸进程。
(可以用ps -ef 查看,进程的状态栏为defunct,这就是所谓的“僵尸”进程)
3. 孤儿进程
孤儿进程指父进程终止或退出后仍在运行的子进程。这类进程会被系统内核的init
进程(PID 为 1)接管,最终由init
负责回收资源。
产生原因:父进程比子进程先结束。
4. wait waitpid
wait, waitpid - 回收进程
#include <sys/types.h>#include <sys/wait.h>pid_t wait(int *wstatus);pid_t waitpid(pid_t pid, int *wstatus, int options);
int *wstatus 状态
退出状态
父进程监听子进程退出状态,如果正常退出,则输出OK
如果子进程异常,退出则输出error
exit(-2)返回给父进程子进程退出状态
wait(&state);
waitpid(-1,&state,WNOHANG );
status == 0 正常退出
status != 0 异常退出
int options
WNOHANG return immediately if no child has exited.
WUNTRACED also return if a child has stopped (but not traced via
ptrace(2)). Status for traced children which have stopped is
provided even if this option is not specified.WCONTINUED (since Linux 2.6.10)
also return if a stopped child has been resumed by delivery of
SIGCONT.
WNOHANG
立即返回,若没有子进程退出。
当返回值ret>0的时候表示子进程退出
当返回值ret=0的时候表示等待子进程的退出
WUNTRACED
若子进程停止(但未被ptrace(2)跟踪),也返回状态。对于被跟踪且停止的子进程,即使未指定此选项,仍会提供其状态信息。
WCONTINUED(自Linux 2.6.10起)
若停止的子进程因收到SIGCONT信号而恢复执行,也返回状态。
wait 阻塞等待回收进程
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main(int argc, char const *argv[])
{printf("hello wprld\n");pid_t id = fork();if (id == -1){printf("fork fail\n");}else if (id > 0){printf("[%d]我是父进程\n", getpid());wait(NULL); //等待子进程执行完毕后再往下执行,阻塞等待回收,循环扫描子进程printf("子进程已回收 结束\n");}else{int count = 10;while (count--){printf("[%d]我子进程%d\n", getpid(), count);sleep(1);}}return 0;
}
waitpid 非阻塞等待回收
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main(int argc, char const *argv[])
{printf("hello wprld\n");pid_t id = fork();if (id == -1){printf("fork fail\n");}else if (id > 0){while(1){int ret = waitpid(-1, NULL, WNOHANG);printf("ret=%d\n", ret);if (ret < 0)break;sleep(1);}//等价//while(waitpid(-1,NULL,WNOHANG)==0); }else{int count = 10;while (count--){printf("[%d]我子进程%d\n", getpid(), count);sleep(1);}}return 0;
}