配套代码笔记仓库。目录目录进程基本知识进程标识符pid进程的产生进程的消亡及释放资源exec函数族用户权限及组权限观摩课:解释器文件system()函数进程会计进程时间守护进程系统日志进程基本知识已经进入多进程阶段进程标识符pid类型pid_t,传统意义上是一个16位有符号整型数。命令ps常用命令:ps axf,ps aux,ps axm,ps ax -L进程号是顺次向下使用// 返回当前进程号 pid_t getpid(void); // 返回父进程的进程号 pid_t getppid(void);进程的产生pid_t fork();以复制(duplicating)当前进程的方式创建一个新进程和setjmp一样,执行一次,返回两次在fork处复制,不会从头运行fork后父子进程的不同之处:fork的返回值不一样pid不同ppid也不同未决信号和文件锁不继承资源利用量清0init进程:1号,是所有进程的祖先进程调度器的调度策略来决定哪个进程先执行fflush()的重要性/* * vfork创建的子进程只能做exec或者exit * ! 基本废弃 */ pid_t vfork(void);进程的消亡及释放资源// 等待进程状态发生变化 pid_t wait(int *status); // 阻塞 pid_t waitpid(pid_t pid, int *status, int options); int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options); wait3(); wait4();分配法和交叉分配法,90%优先选择交叉分配法。池类算法:上游往池子里放任务,下游三个线程从池子里取任务。exec函数族eg. bash进程创建primer进程// exec函数族:替换当前进程的映像 extern char **environ; 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[]); 用户权限及组权限u+s:如果文件是可执行的,则执行文件时,是以文件的拥有者的权限执行的。-rwsr-xr-x 1 root root 68248 Mar 23 2023 /usr/bin/passwd所以普通用户执行passwd时,是以root的权限执行的。g+s:如果文件是可执行的,则执行文件时,是以文件的所在组的权限执行的。uid和gid都有三种类型:real uid:进程的实际所有者effective uid:进程的有效所有者saved uid:进程的保存的有效所有者shell获取身份的流程 fork exec fork init -->--> getty -->--> login -->--> shell exec exec root root root user// 获取当前用户的real uid uid_t getuid(void); // 获取当前用户的effective uid uid_t geteuid(void); // 获取当前进程的real gid pid_t getegid(void); // 获取当前进程的effective gid pid_t getgid(void); // 设置当前进程的real uid int setuid(uid_t uid); // 设置当前进程的effective uid int seteuid(uid_t uid); // 设置当前进程的real gid int setgid(gid_t gid); // 设置当前进程的effective gid int setegid(gid_t gid); // 交换uid和gid (原子操作) int setreuid(uid_t ruid, uid_t euid); // 交换gid和egid (原子操作) int setregid(gid_t rgid, gid_t egid); 观摩课:解释器文件unix讲究机制而非策略脚本,后缀名是什么都可以,一般用sh, exec#!/bin/cat # some shell#!是一种约定俗成的标记,告诉系统这个脚本应该用什么解释器来执行。system()函数/* * 运行一个shell命令 * 调用/bin/sh */ int system(const char *command);相当于fork+exec+wait的封装进程会计//! freeBSD系统的方言 int acct(const char *filename);进程时间clock_t times(struct tms *buf); // clock_t 滴答数 struct tms{ clock_t tms_utime; /* user time */ clock_t tms_stime; /* system time */ clock_t tms_cutime; /* user time of children */ clock_t tms_cstime; /* system time of children */ } 守护进程守护进程PPID为1守护进程没有控制终端,TTY为?PID, PGID, SID相同pid_t setpgid(pid_t pid, pid_t pgid); pid_t getpgid(pid_t pid); pid_t getpgrp(void); //! 方言 pid_t getpgrp(psid_t pid); //! 方言会话(session):一个或多个进程组的集合,以sid为标识pid_t setsid(void);setsid必须由非leader进程调用,从而创建一个新的会话。前台进程组:正在与终端交互的进程组后台进程组:正在运行,但不与终端交互的进程组终端:我们接触的都是虚拟终端单实例守护进程:锁文件/var/run/name.pid启动脚本文件:/etc/rc*...系统日志syslogd服务#include <syslog.h> /** * 打开系统日志 * * @prarm: ident 标识符 * @prarm: option 选项 LOG_CONS, LOG_NDELAY, LOG_NOWAIT, LOG_PERROR ... * @prarm: facility 来源 LOG_USER, LOG_DAEMON, LOG_KERN, LOG_LOCAL0~7 ... */ void openlog(const char *ident, int option, int facility); /** * 记录系统日志 * * @prarm: priority 优先级 以 ERR 与 WARNING 为分界点 * @prarm: format 格式化字符串 * @prarm: ... 格式化参数 */ void syslog(int priority, const char *format, ...); /** * 关闭系统日志 */ void closelog(void);sudo tail /var/log/messages # 老师 journalctl -r # 我的debian