程序的三张状态
- 就绪态
- 执行态
- 阻塞态
4个G的虚拟地址空间一般这样划分:
- 0-3G 用户空间
- 3-4G 内核空间
程序的存储空间
- 数据区 .data—->初始化数据段,如初始化的全局变量,初始化的静态变量
- BSS区 .bss —->未初始化数据段,意为:由符号开始的块(block started by symbol),如未初始化的全局变量,未初始化的静态变量
- 栈区 .stack —–>局部变量
堆区 .heap —–>动态分配的空间
只读常量区 .rodata
- 文本区 .text
- 信号的相关API
pid_t pid = fork();
出错返回-1,父进程返回>0的数,即子进程的PID,子进程返回0
- 宏函数
exit(status);
exit(0);
exit(1);
- 另外几个相关函数
wait(&status)/waitpid(pid,&status,options)
execl(path,a.out,arg1,arg2,...,NULL);
system("ls -l");
进程间通信:
- 两个/多个进程之间的数据交换,叫进程间通信
- 由于进程的地址空间相对独立,进程间通信需要专门的机制。
- 信号、管道、消息队列、共享内存、信号量、套接字(网络编程)
1.信号
- 中断
- 硬件中断
- 软件中断
- 信号的本质说法是软中断,可以作为进程间通信的一种机制,更重要的是可以中断一个正常运行的程序,更多地被用于处理意外情况。
- 基本特点:
- 1.信号是异步的,不知道何时到到达
- 2.进程可以处理信号,也可以给其它进程发送信号、
- 3.每个信号都有一个名字,都以SIG开头。
- kill -l 查看系统所支持的所有信号
- killall 进程名
- kill -9 pid
- 常用的信号有:
- 2) SIGINT 终止进程 ctrl+c
- 9) SIGKILL 杀掉进程
- 11) SIGSEGV 段错误
- 13) SIGPIPE 管道破裂
- 14) SIGALRM 闹钟
- 17) SIGCHLD 子进程结束
- 中断
信号处理方式:
- 1.默认处理 绝大多数信号的默认处理都是终止进程
- 2.忽略处理 SIGKILL不能忽略
- 3.自定义处理 只需要写一个信号处理函数
信号处理的实现步骤:
- 1.写一个信号处理函数
- 2.用signal注册信号的处理方式
1.信号注册函数:
#include <signal.h>
sighandler_t signal(int signum, sighandler_t handler);
- 第一个参数:信号的名称/值(表示处理的是哪一个信号)
第二个参数:信号的处理方式
- SIG_IGN 忽略
- SIG_DFL 默认
- 函数指针 自定义
- 自定义的信号处理函数原型:
void sig_handle(int signo);
思考:对于fork创建的子进程,对于信号的处理方式与其父进程有什么不同?
2.发送信号:
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
- 功能:给指定的进程发送指定的信号
- 第一个参数:进程的PID
- 第二个参数:要发送的信号名称/值
返回值:成功返回0,失败返回-1,errno被设置
3.给自己(调用进程)发信号:
#include <signal.h>
int raise(int sig);
- 4.闹钟函数:
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
- 功能:用于根据参数指定的秒数之后发送一个SIGALRM信号
- 参数:秒数,如果参数为0,取消之前设置的闹钟
- 返回值:成功返回上一个闹钟没有来得及响应的秒数,之前没有设置闹钟,则返回0