github_520 发表于 2020-11-14 16:06

操作系统一些笔记 进程和线程

1 进程进程模型:每个系统有自己的虚拟CPU,但CPU又在不同进程之间进行切换。一个进程就是一个正在执行的程序,包括程序寄存器和变量当前的值。进程是某种类型的活动,它有程序。输入和输出以及状态。单个处理器可被若干进程共享,使用某种进程调度算法,决定何时停止一个进程的工作,并转而为另一个进程提供服务。1.1进程的创建:系统初始化,正在运行的程序执行了创建进程的系统调用,用户请求创建一个新进程,一个批处理作业初始化。父进程(英语:Parent Process)指已创建一个或多个子进程的进程。1.2进程的终止:正常退出,出错退出,严重错误,被其他进程杀死1.3进程的层次结构:进程和它的所有子进程以及后裔共同组成一个进程组。Linux是一个树结构 Windows中是地位相同,每个进程地位都是相等的,句柄标识父与子进程1.4进程的状态:运行态 就绪态,阻塞态运行态和就绪态是由调度程序引起的,1.5进程的实现:2.线程每个进程有一个进程空间和一个控制线程,在一个应用中也发生着许多活动。并行实体拥有共享同一个地址空间和所有可用数据的能力。进程比线程更轻量级,实现并行计算。多个线程可以共享公共 内存,允许他们同时访问同一个文件夹,三个进程做不到。所有线程会有完全一样的内存空间一个进程打开了文件,该文件对该进程中其他线程都可见每个线程都有自己的堆栈在用户空间中实现线程:内核对线程包一无所知,从内核角度考虑,但线程进程。用户级线程包可以在不支持线程的操作系统上实现。#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#define NUMBER_OF_THREADS 10
void *print_hello_world(void *tid)
{
    printf("Hello World.Greeting from thread %d\n",tid);
    pthread_exit(NULL);
}
int main()
{
    pthread_t threads;
    int status,i;
    for(i=0;i<NUMBER_OF_THREADS;i++)
      printf();
}进程和线程有一个关键的差别:线程完成时,把线程信息保存在线程表中,调用线程带哦都程序来选择另一个要运行的线程。不需要陷入内核,不需要上下文切换。不需要对内存告诉缓存进行刷新。某个程序调用或者跳转到了一条不存在的内存指令上,就会发生页面故障在内核中实现线程:3.进程间通信两个或多个进程写某些共享数据,最后结果取决于运行的精准时序,称为竞争条件临界区:避免竞争条件需要的是互斥条件:确保某个进程在使用文件夹或者共享变量时候,其他进程不会进行同样的操作。共享内存进行访问的程序片段称为临界区域,适当安排,使得两个进程不可能同时处于临界区内,避免竞争条件。忙等待的互斥:1.屏蔽中断:每个进程刚进入临界区后立即屏蔽所有中断,并在就要离开之前再打开所有中断。CPU只有发生时钟中断时候才会进行进程切换,屏蔽后的CPU不会被切换到其他中断。缺点是对于多核处理器不能使用。2.锁变量:检查,如果内存被占用则设为1,反之为0,0表示临界区内没有进程。但可能会发生同时进入而造成竞争条件。3.严格轮换法:连续测试一个变量值直到某个值出现为止,称为忙等待两个进程严格轮流进入临界区,while(TRUE)
{
while(turn!=0);
critical_region();
turn=1;
noncritical_region();
}4.Peterson解法#define FALSE 0
#define TRUE 1
#define N 2
int turn;
int interested;
void enter_region(int process)
{
int other;//另一个进程号
other=1-process;//另一个进程
interested=TRUE;//表示感兴趣
turn =process;//设置标志
while(turn==process&&interested==TRUE);//空语句
}
void leave_region(int process)
{
    interested=FALSE;
}5.信号量file://C:/Users/123/AppData/Roaming/Typora/typora-user-images/1603195016154.png?lastModify=1605341113
[*]在缓冲区为空时,消费者不能再进行消费
[*]在缓冲区为满时,生产者不能再进行生产
[*]在一个线程进行生产或消费时,其余线程不能再进行生产或消费等操作,即保持线程间的同步
[*]注意条件变量与互斥锁的顺序      因此需要保持线程间的同步,即一个线程消费(或生产)完,其他线程才能进行竞争CPU,获得消费(或生产)的机会。对于这一点,可以使用条件变量进行线程间的同步:生产者线程在product之前,需要wait直至获取自己所需的信号量之后,才会进行product的操作;同样,对于消费者线程,在consume之前需要wait直到没有线程在访问共享区(缓冲区),再进行consume的操作,之后再解锁并唤醒其他可用阻塞线程。
file://C:/Users/123/AppData/Roaming/Typora/typora-user-images/1603195156901.png?lastModify=1605341113假设缓冲区大小为10,生产者、消费者线程若干。生产者和消费者相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池中取走一个消息。
[*]items代表缓冲区已经使用的资源数,spaces代表缓冲区可用资源数
[*]mutex代表互斥锁
[*]buf 代表缓冲区,其内容类型为item
[*]in、out代表第一个资源和最后一个资源var items = 0, space = 10, mutex = 1;
var in = 0, out = 0;
item buf = { NULL };

producer {
    while( true ) {
      wait( space );// 等待缓冲区有空闲位置, 在使用PV操作时,条件变量需要在互斥锁之前
      wait( mutex );// 保证在product时不会有其他线程访问缓冲区

      // product
      buf.push( item, in );// 将新资源放到buf位置
      in = ( in + 1 ) % 10;
      
      signal( mutex );// 唤醒的顺序可以不同
      signal( items );// 通知consumer缓冲区有资源可以取走
    }
}

consumer {
    while( true ) {
      wait( items );// 等待缓冲区有资源可以使用
      wait( mutex );// 保证在consume时不会有其他线程访问缓冲区

      // consume
      buf.pop( out );// 将buf位置的的资源取走
      out = ( out + 1 ) % 10;

      signal( mutex );// 唤醒的顺序可以不同
      signal( space );// 通知缓冲区有空闲位置
    }
}

6.调度      有多个进程同时竞争CPU,只要有两个或更多的进程处于就绪状态,这种情况就会发生。完成选择工作的这一部分程序称为调度程序,使用的算法称为调度算法。6.1先来先服务:6.2最短作业优先6.3最短剩余时间优先交互式系统中的调度:轮转调度 优先级调度 多级调度2.内存管理1.地址空间把物理地址暴露给进程会带来严重的问题:1.用户程序破坏操作系统,使得系统慢慢停止运行2.同时运行多个程序几乎不可能多个程序同时处于内存中,不影响,需要 保护和重新定位地址空间为程序创造了一种抽象的内存,地址空间是一个进程可用于寻址内存的一套地址集合。基址寄存器与界限寄存器交换技术:处理内存超载,将空闲进程存储在磁盘上。不运行时不会使用内存。分配额外内存虚拟内存:每个进程有自己的进程空间,

袁煜914 发表于 2020-11-14 16:52

NvidiaChina 发表于 2020-11-14 17:08

看不懂,但是一定很厉害
页: [1]
查看完整版本: 操作系统一些笔记 进程和线程