dup() 和 dup2()
int dup(int oldfd);
功能:复制文件描述符
参1:已有的文件描述符
返回:新的文件描述符
此函数更多用在对已有的文件描述符进行保存
int dup2(int oldfd, int newfd); //(更常用)
功能:复制文件描述符,重定向
返回:新文件描述符
旧文件描述符复制给新文件描述符,即 新文件描述符指向旧文件描述符
fcntl()函数实现dup:(知道有它就行了,不常用,有dup()谁爱用它?)
int fcntl(int fd, int cmd, ...);
参2:F_DUPFD
参3:被占用的,返回最小可用的
未被占用的,返回=该值的文件描述符
/*****************************************************************************/
进程:
程序:死的。只占用磁盘空间。 ——剧本。
进程;活的。运行起来的程序。占用内存、cpu等系统资源。 ——戏。
时钟中断:在并发时,系统通过中断让进程让出CPU资源。
cache:缓存
MMU:虚拟内存映射单元,在CPU内部,负责调配虚拟内存与物理内存之间的映射关系。
两个进程,用户空间被MMU映射到不同的物理内存中,内核空间映射到相同的物理内存中。
PCB进程控制块:是一个结构体,位于内核空间(3G-4G)某一区域中。
进程id (ps aux | grep 进程名)这个可以查进程的状态
进程状态: 初始态、就绪态、运行态、挂起态、终止态。wait、sleep函数就是把进程挂起几秒钟。
进程当前工作目录位置
umask掩码
文件描述符表
信号相关信息资源
用户id和组id
等等...
常见的环境变量:
PATH 记录可执行文件目录位置
echo $PATH 这样可以看环境变量PATH的值
echo $CC CC代表当前终端的编译环境
SHELL 解析命令的,当前shell,它的值通常是/bin/bash
fork函数:
pid_t fork(void);
创建子进程。有两个返回值,父子进程有各自的返回值。父进程返回子进程pid。 子进程返回 0.
getpid(); 获取自己的PID
getppid(); 获取自己父进程的PID
循环fork()N次,会创建 (2^n)-1 个子进程。每个子进程标识自己的身份。
父子进程在fork()后的相同之处:
前提是刚fork()后。fork()后执行一段时间程序后,父子进程就不一定有相同之处了
相同之处有:data段、text段、堆、栈、环境变量、全局变量、宿主目录位置、进程工作目录位置、信号处理方式等相同
父子进程不同:
进程id、fork()返回值、各自的父进程、进程创建时间、闹钟、未决信号集等不同
父子进程共享:
父子进程至之间共享:1.文件描述符(打开文件的结构体) 2.mmap建立的映射区
父子进程之间遵循“读时共享、写时复制”的原则,这个原则绝大多数是应用于全局变量
若父进程给全局变量写了一个新值,其实父进程写进了复制后的全局变量中,子进程读到的还是复制之前的全局变量值(旧值)
躲避父子进程共享全局变量的误区
无论子进程执行父进程的逻辑还是执行自己的逻辑,都能节省内存开销
特别的,fork()之后,父进程先执行还是子进程先执行,取决于内核所使用的调度算法