操作系统小结

线程的引入是为了减少程序在并发执行时所付出的时空开销,使os具有更好的并发性。
线程和进程比较
1)调度
在传统的os中,进程是资源分配的基本单位,也是一个能独立运行和调度的基本单位。而在引入了线程的os中,进程仍然作为资源分配的基本单位,而独立运行和调度的基本单位变成了线程,线程只拥有自己需要的少量资源即可工作。
2)切换
在引入了线程的os中,同一进程中, 线程的切换不会引起进程的切换,但从一个进程中的线程切换到另外一个进程的线程中,则需要进程的切换。
3)并发性
在引入了线程的os中,不仅进程之间可以并发执行,而且在一个进程中的多个线程也可以并发执行,使得os具有更好的并发性,从而能更加有效地提高系统资源的利用率和系统的吞吐量。
4)拥有资源
不论是传统的os还是引入了线程的os,进程都是资源分配的基本单位。一般而言,线程自己不拥有系统资源(只是运行必不可少的而已),但是它可以访问其隶属的进程资源。一个进程中的所有线程可以使用该进程的所有资源。
5)系统开销
在创建或撤销进程时,系统都要为之创建和回收进程控制块,分配或回收资源,os所付出的开销要远大于线程进行同样操作时需要的花销。


信号量机制
1)信号量机制是dijkstra为解决进程同步问题而提出的一种进程同步机制。一共分为4种:整型信号量机制、记录型信号量机制、and信号量机制、信号量集机制。
整型信号量机制就是需要某种资源就通过wait操作申请资源,用完就是用signal操作释放,这两个操作是原子操作,所以不符合让权等待的同步机制的4个原则。
2)为了解决整型信号量机制无法让权等待的问题,提出了改进的记录型信号量,具体实现就是通过一个block队列来保存无法获得资源的进程,绝对值代表因缺少该资源而放入等待队列的进程数目。如果无法获得该类资源,就放弃处理机进入阻塞队列,等到有空闲资源时,就查看阻塞队列中是否有等待的进程。
3)and信号量就是针对一个进程需要多个资源提出的,如果2个进程a,b,都需要2个资源c,d,但是a先获得了c,b先获得了d,那么,就死锁了,因为都不想释放。and信号量机制就是对一个进程所需要的资源要么全部分配,要么全部都不分配(只要其中一个资源没有空闲就不分配)
4)信号量集机制是对于多个进程分别需要多个资源提出的。是上述同步机制的集大成者。
一般形式为:swait(s1,t1,d1,.....sn,tn,dn)其中s为信号量,d为需求值,t为下限值。因为是and型信号量的扩充,所以也是要么全部分配,要么全部不分配两种选择。
 
程序执行流程http://wenku.baidu.com/view/a1cb31671ed9ad51f01df2fa.html


处理机调度一共有三种:高级调度、中级调度、低级调度
1)高级调度就是作业调度,就是根据某种算法,把外村上处于后备队列中的那些作业调入内存,调度对象为作业。
2)低级调度就是进程调度,调度对象为进程,用于决定就绪队列中的哪个进程应获得处理机,再燃再由分配程序执行把处理机分配给该进程的具体操作。
3)中级调度就是存储器管理中的对换功能,主要目的是为了提高内存利用率和系统吞吐量。


产生死锁的必要条件
1)互斥条件:进程对分配的资源进行排他性使用,即某资源只能被一个申请到该资源的进程独自使用,其他申请者只能等待。
2)请求和保持条件:进程已保持了一个资源又需要另一个资源而得不到满足时,就是阻塞,但是不释放已获得的资源。
3)不剥夺条件:进程获得的资源未使用完之前不能被剥夺,只能在使用完后由自己释放。
4)环路等待条件:发生死锁时,必然存在一个资源竞争的环路。


处理死锁的基本方法
1)预防死锁。通过设置限制条件,去破坏产生死锁的4个条件的一个或几个条件。但是往往由于限制条件过于严格,因而对系统的资源利用率和吞吐量有一定的影响(下降)。
2)避免死锁。也是事先预防的策略。利用某种安全算法防止系统进入不安全状态,施加的限制条件比较弱。(银行家算法)
3)检测死锁。事先不采取任何限制性措施,允许系统在运行过程中出现死锁。但是可以通过系统的检测机构发现死锁的信息并采取相应措施解除死锁。
4)解除死锁。与检测死锁配合使用。实现起来难度较大。


死锁定理
S为死锁状态的充分条件是:当且仅当S状态的资源分配图是不可完全简化的。



(1)进程的软中断通信 #include #include #include #include int wait_flag; void stop(); main( ) { int pid1, pid2; // 定义两个进程号变量 signal(2,stop); // 或者 signal (14,stop); while((pid1 = fork( )) == -1); // 若创建子进程1不成功,则空循环 if(pid1 > 0) { // 子进程创建成功,pid1为进程号 while((pid2 = fork( )) == -1); // 创建子进程2 if(pid2 > 0) { wait_flag = 1; //sleep(1); // 父进程等待5秒 kill(pid1,SIGUSR1); // 杀死进程1 kill(pid2,SIGUSR2); // 杀死进程2 wait(0); wait(0); printf("\n Parent process is killed !!\n"); exit(0); // 父进程结束 } else { wait_flag = 1; signal(SIGUSR2,stop); // 等待进程2被杀死的中断号17 printf("\n Child process 2 is killed by parent !!\n"); exit(0); } } else { wait_flag = 1; signal(SIGUSR1,stop); // 等待进程1被杀死的中断号16 printf("\n Child process 1 is killed by parent !!\n"); exit(0); } } void stop() { wait_flag = 0; } (2)进程的管道通信 #include #include #include int pid1,pid2; // 定义两个进程变量 main( ) { int fd[2]; char OutPipe[100],InPipe[100]; // 定义两个字符数组 pipe(fd); // 创建管道 while((pid1 = fork( )) == -1); // 如果进程1创建不成功,则空循环 if(pid1 == 0) { lockf(fd[1],1,0); // 锁定管道 sprintf(OutPipe,"\n Child process 1 is sending message!\n"); write(fd[1],OutPipe,50); // 向管道写入数据 sleep(5); // 等待读进程读出数据 lockf(fd[1],0,0); // 解除管道的锁定 exit(0); // 结束进程1 } else { while((pid2 = fork()) == -1); // 若进程2创建不成功,则空循环 if(pid2 == 0) { lockf(fd[1],1,0); sprintf(OutPipe,"\n Child process 2 is sending message!\n"); write(fd[1],OutPipe,50); sleep(5); lockf(fd[1],0,0); exit(0); } else { wait(0); // 等待子进程1 结束 read(fd[0],InPipe,50); // 从管道中读出数据 printf("%s\n",InPipe); // 显示读出的数据 wait(0); // 等待子进程2 结束 read(fd[0],InPipe,50); printf("%s\n",InPipe); exit(0); // 父进程结束 } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值