6.1 KiB
6.1 KiB
目录
进程基本知识
已经进入多进程阶段
进程标识符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也不同- 未决信号和文件锁不继承
- 资源利用量清0
init进程: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