进程创建
- 父进程创建若干个子进程:后者再创建其子进程:以此内推,构成了反映"传承"关系的一颗进程树
子进程的资源
- 子进程共享父进程的所有资源
- 子进程共享父进程的部分资源
- 子进程不从父进程共享资源,重新独立申请
执行代码的执行顺序
- 父进程和子进程并发执行
- 父进程在子进程执行期间等待,待子进程执行完毕后才恢复执行余下代码
linux c代码:
1 #include <stdio.h>
2 #include <sys/types.h>
3
4 int main(void)
5 {
6 pid_t pid;
7 pid = fork();//创建子进程,返回的是创建的子进程的编号
8 //创建完成之后等待父进程让出cpu进行执行,子进程创建时深拷贝父进程的资源
9 //子进程执行时不执行此行代码
10 if(pid<0)//创建进程出错
11 {
12 printf("Fork Failed");
13 exit(-1);
14 }
15 else if(pid==0)//子进程执行时候的代码
16 {
17 printf("这是子进程的输出:
");
18 execlp("/bin/ls","ls",NULL);
19 }
20 else//父进程执行
21 {
22 wait(NULL);//父进程等待子进程完成执行
23 printf("子进程创建完毕,父进程退出
");
24 exit(0);
25 }
26 return 0;
27 }
运行结果:
进程终止
"进程终止"的语义之一:子进程执行完成最后一条指令后,要求操作系统将自己杀出(exit).语义动作含:
- 子进程传递数据给父进程(通过父进程的wait操作)
- 子进程的资源被操作系统收回
"进程终止"语义之二:父进程终止子进程的执行(abort).终止原因可能是:
- 子进程超额使用系统资源
- 早前交给子进程执行的任务,过期无效了
进程与进程不能完全独立,还要进行进程间合作
- 独立进程不会影响其他进程的执行,也不会被影响
- 合作进程影响其他进程,或者受其影响
- 进程间合作是必须的,带来的好处:
1.共享信息
2.加速(计算)执行速度
3.模块化
4.方便调用,等等......
一个经典问题:生产者-消费者问题
生产者进程"生产"出消息,存储在缓冲区,供消费者进程"消费"
共享内存的解决方案
数据结构:
#define BUFFER_SIZE 10
Typedef struct{
.......
}item;
item buffer[BUFFERSIZE];
int in=0;
int out = 0;
解决方案可行
但是只能用足BUFFER_SIZE-1个缓冲单元
生产者:
消费者:
两个变种
同步通信和异步通信
同步通信
发送操作send:发送进程等待,直至接受到进程确认收到消息
接受操作receive:接受进程等待,直至有个消息到达
异步通信
发送操作send:发送进程发出消息后即返回,该干什么干什么,不理会消息是否送达
接收操作receive:接收进程执行一次接收动作,要么收到一条有效消息,要么收到空消息