Linux进程
进程号为0的进程是调度进程,是内核的一部分系统进程
进程号为1的是init进程,。i n i t通常读与系统有关的初始化文件( / e t c / r c*文件),并将系统引导到一个状态(例如多用户),通常表现为/sbin/init
进程号为2的是是页精灵进程( p a g e d a e m o n )。此进程负责支持虚存系统的请页操作。与交换进程一样,页精灵进程也是内核进程。
fork() 返回0为子进程,子进程拷贝父进程的所有数据,有自己的地址空间
vfork() 子进程不拷贝父进程的数据,在父进程的地址空间内执行,一般用于exec
void(* signal(int sig, void(*func)(int)))(int)
进程优先级
int getpriority(int which, id_t id)
int setpriority(int which, id_t id)
which: PRIO_PROCESS 进程id为。。。
PRIO_PGRP 进程组id为。。。
PRIO_USER 用户id为某某的优先级
fork后子进程的特点
1.有自己的进程id,父进程
2.有父进程的文件描述字副本(系统打开文件表项相同,包括了文件状态标签(open的flags参数)、文件当前位置和指向该文件v-node的ptr)
3.进程所耗费的时间全部置0
4.进程的悬挂信号和悬挂的时钟定时器都被清除。但是继承父进程的信号屏蔽位和信号动作
5.不继承父进程的文件锁
执行新程序
int execl(const char* path, arg1, arg2, ..., 0); "/bin/passwd",0
int execlp(const char* file, arg1, arg2, ..., 0); "passwd", 0
int execle(const char* path, arg1, arg2, ..., 0, const char** envp); "/bin/passwed", 0, envp
int execv(const char* path, char** args)
int execvp(const char* file, char** args)
int execve(const char* path, char** args, char** envp);
exec后的进程跟原先的进程基本保持不变,主要有几点变化
1. 调用进程打开的目录流被关闭
2. 如果调用进程 fcntl(fd, SET_FD, FD_CLOEXEC) 后,那么exec后将关闭改文件
3. exec后先前注册的atexit()函数将不再是注册的
4. 如果新进程映像文件的调整用户id位被设置时。则exec后的有效用户id将会被设置为新进程映像文件的属主id (比如passwd)
等待进程完成#include
wait(int* return_state)
waitpid(int pid, (int*)return_state, options) pid=-1 等同wait,等待任意子进程
pid>0等待某个子进程
pid=0 等待同进程组id相同的任意子进程
pid<-1 等袋同进程组id的某一个子进程
options = 0 阻塞等待
options = WNHANG 非阻塞等待
信号
#include
分类:
硬中断 不可预测的,由设备(驱动程序)产生的。 crtl+c 或者 网卡得到数据
软中断 程序错误或者显示请求。可以预测的,由程序本身产生的。如浮点异常,非法指令,定时器(程序产生的模拟)
void(* signal(int sig, void (*func) (int)))(int)
SIG_DFL SIG_IGN 是两个变量
int sigaction(int sig, struct sigaction* act, struct sigaction* old_act);
struct sigaction
1. void(* sa_handler)(int) 默认的函数句柄
2. void(* sa_sigaction)(int, siginfo*, void*) 当sa_flags设置SA_SIGINFO时的函数句柄(siginfo包含了产生信号的原因,void*包含了被中断进程的京城上下文)
3. sigset_t sa_mask 屏蔽的信号集合(SIGKILL SIGSTOP不能被阻塞)
4. int sa_flags SA_NOCLDSTOP 子进程暂停时不发送SIGCHLD给父进程(默认是发送的)
SA_RESTART 进程正在系统调用的时候被信号中断,恢复后重新开始系统调用,而不是产生一个EINTR的错误
SA_NODEFFER 信号句柄执行时,不阻塞同样的信号执行
SA_NOCHLDWAIT父进程不必wait子进程,子进程不会变成僵死进程
实现信号屏蔽也可以通过sigpromask(int how, sigset_t* set, sigset_t* oldset)来实现
SIG_BLOCK //阻塞set里面的信号加到当前进程的信号屏蔽位中
SIG_UNBLOCK //从当前进程的信号屏蔽位中放开set里面的信号
SIG_SETMASK //设置进程的信号屏蔽位为set
产生信号
int raise(int sig)产生一个sig给当前进程
int kill(pid_t pid, int sig)长生一个sig给pid的进程
pid>0发送给进程id为pid的进程
pid<-1发送给同进程组的进程id为 pid绝对值 的进程
pid=0发送给同进程组的所有进程
-1没有定义
sigset_t一般是实现为int
int sigemptyset(sigset_t*); //没有任何信号
int sigfillset(sigset_t*); //设置所有信号
int sigaddset(sigset_t*, int);
int sigdelset(sigset_t*, int);
int sigismember(const sigset_t*, int);
检查悬挂信号
int sigpending(sigset_t* set) //将当前的进程信号屏蔽位存储在set里面
等待信号到达
int pause() //等待任意一个信号的到达
int sigsuspend(const sigset_t* sigmask)
阅读(2377) | 评论(0) | 转发(0) |