1.进程标识符
①pid,通常是一个有符号的,16位的一个整形数
我在centos下测试了 是占四个字节
②类型pid_t
③文件描述符优先使用最小的,但是进程描述符是一次使用最小的,就算前面有释放的,也不会使用
④两个函数getpid和getppid
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
printf("MyPid = %d\n", getpid());
printf("Father Pid = %d\n", getppid());
printf("SIZE = %d\n", sizeof(pid_t));
return 0;
}
2.fork
NAME
fork - create a child process
SYNOPSIS
#include <unistd.h>
pid_t fork(void);
DESCRIPTION
fork() creates a new process
by duplicating the calling process.
①通过复制父进程来创造一个新的进程,注意是连执行到的位置都一模一样,类似于memory copy,当然这么理解有些牵强
except for the following points
①首先fork的返回值不同
②父子进程的pid不同,ppid也不同
③子进程不继承父进程设置的文件锁
④子进程的未处理闹钟被清除
⑤子进程的未处理信号集变成空集
fork的返回值
①当创建子进程失败的时候,会返回-1
②当创建子进程成功的时候,子进程会接收到返回值0,父进程会接收到返回值是子进程的pid号
一个demo
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int pid;
printf("[%d]: Begin\n", getpid());
pid = fork();
if(pid < 0)
{
perror("fork()");
exit(1);
}
if(0 == pid)
{
printf("[%d]: Child Working\n", getpid());
}
else
{
printf("[%d]: Father Working\n", getpid());
}
printf("[%d]: End\n", getpid());
return 0;
}
3.init进程是所有进程的祖先进程
4.永远不要凭空猜测父子进程谁先被调度
5.一个需要注意的问题
还是刚才那个程序,我们对其进行重定向,发现为什么会被打印两次呢?
没有刷新缓冲,你在输出到终端的时候,终端是行缓冲,所以只打印了一次
fflush(NULL)
6.
①当父进程死了,子进程还在,那么子进程会变成孤儿进程,会被init进程接管
②当子进程死了,父进程还在运行,那么子进程会变成僵尸进程