刚把《unix环境高级编程》看完,就迫不及待的写几篇
文章记录一下相关的知识点。我觉得总共就这个几个方面
进程、线程,io(系统io,c库函数,再来点通信io)。现在
先来一发通过接口控制进程的生命周期。
进程基本知识
我们写源码编译成可执行文件,我们运行可执行文件生成进程
进程处理我们job,跟用户打交道的就是进城了。每个进程都有自己
的进程标识(非负整数)是唯一的,但是进程标示是可以复用的
当一个进程结束后它的进程id就可以被别的新进程使用。当然了每
个进程也有自己的进程空间,进程空间大家都很熟悉了,进程空间
采用虚拟存储技术,让我们可以运行大于我们内存的程序。内存空间
主要:进程环境变量,进程栈, 匿名内存分配 ,堆,未初始化全局变量
初始化全局变量,正文(程序)。总的来说进程和程序的区别就是进程
是动态的并且包含程序的内容,程序是静态的就是一个文件。
进程创建
进程的创建过程就是pcb创建(分配资源)并且插入到就绪队列的过程。
在unix中我们使用的 是 fork 函数
1 2 3
| #include <unistd.h> pid_t fork(void); 返回值:子进程返回0,父进程返回子进程ID;若出错,返回-1
|
fork 子进程复制父进程进程空间但是共享正文部分,文件描述符也复制
就相当于执行了 dup 函数一样。
进程结束
正常结束
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| #include <stdlib.h> void exit(int status); void _Exit(int status); #include <unistd.h> void _exit(int status); 其中exit函数结束之前,会调用fflush函数,冲洗缓冲区 _Exit _exit 函数 不冲洗缓冲区直接结束进程。 main 函数中的return 相当于exit 函数,效果一样。 ``` # 父进程阻塞等待子进程结束 ``` #include <sys/wait.h> pid_t wait(int *statloc); pid_t waitpid(pid_t pid, int *statloc, int options); 俩个函数返回值:若成功返回进程id,若出错返回0 参数: statloc 为NULL 则标示不关注终止进程状态, 整形指针 指向结束子进程的状态地址 在一个子进程终止前,wait使其调用者阻塞 ``` # 进程阻塞 ``` #include <unistd.h> int pause(void); 返回值:-1,errno 设置为 EINTR 只有执行了一个信号处理程序并从其返回时,pause才返回。在这种情况下 pause返回-1, errno 设置为EINTR。 unsigned int alarm(unsigned int seconds); 返回值:0或以前设置的闹钟时间的余留秒数 sleep(int seconds) ;这个函数大家应该都很熟悉吧,那大家有木有自己 写过这个函数,或者知道这个函数是怎么实现的呢,其实我们可以通过alarm 这个函数定时,然后让进程阻塞(pause),时间到之后唤醒进程就可以达到sleep的效果 不过因为涉及到了信号的处理需要考虑竞度问题,因为alarm时间到了之后系统 会给你发出信号,信号处理完之后会继续执行pause之后的。下面是一个简单的例子 unsigned int sleep1(unsigned int seconds) { if (signal(SIGALRM, sig_alrm) == SIG_ERR) return(seconds); alarm(seconds); pause(); return(alarm(0)); } ``` # 进程唤醒 进程的阻塞一般使用 pause函数,pause函数会在进程处理完一个信号程序并返回时 才返回,也就是唤醒进程, 所以唤醒一个进程最简单的办法就是在pause之前,给进程 注册一个信号,然后使用kill函数给该进程发送一个注册过的信号
|
#include <signal.h>
int kill<pid_pid, int signo);
raise(int signo);
返回值:若成功返回0,出错返回-1
rasie 向自身发送信号 raise(signo) == kill(getpid(), signo)
pid > 0 将信号发送给进程id为pid的进程
pid == 0 将信号发送给与发送进程同一个进程组的所有进程(具有权限)
pid < 0 将信号发送给其进程组id等于pid绝对值的进程组的所有进程(具有权限)
pid == -1 将信号发送给发送进程有权限向他们发送信号的所有进程。
```