linux线程信号进程,LINUX 进程与线程 信号量 通信

操作系统 进程与线程 信号量 通信

1 进程

进程模型:每个系统有自己的虚拟CPU,但CPU又在不同进程之间进行切换。一个进程就是一个正在执行的程序,包括程序寄存器和变量当前的值。

进程是某种类型的活动,它有程序。输入和输出以及状态。单个处理器可被若干进程共享,使用某种进程调度算法,决定何时停止一个进程的工作,并转而为另一个进程提供服务。

1.1进程的创建:系统初始化,正在运行的程序执行了创建进程的系统调用,用户请求创建一个新进程,一个批处理作业初始化。父进程(英语:Parent Process)指已创建一个或多个子进程的进程。

1.2进程的终止:正常退出,出错退出,严重错误,被其他进程杀死

1.3进程的层次结构:进程和它的所有子进程以及后裔共同组成一个进程组。

Linux是一个树结构 Windows中是地位相同,每个进程地位都是相等的,句柄标识父与子进程

1.4进程的状态:运行态 就绪态,阻塞态

运行态和就绪态是由调度程序引起的,

1.5进程的实现:

2.线程

每个进程有一个进程空间和一个控制线程,在一个应用中也发生着许多活动。并行实体拥有共享同一个地址空间和所有可用数据的能力。进程比线程更轻量级,实现并行计算。

多个线程可以共享公共 内存,允许他们同时访问同一个文件夹,三个进程做不到。所有线程会有完全一样的内存空间

一个进程打开了文件,该文件对该进程中其他线程都可见

每个线程都有自己的堆栈

在用户空间中实现线程:内核对线程包一无所知,从内核角度考虑,但线程进程。用户级线程包可以在不支持线程的操作系统上实现。

#include

#include

#include

#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[NUMBER_OF_TH];

int status,i;

for(i=0;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[N];

void enter_region(int process)

{

int other;//另一个进程号

other=1-process;//另一个进程

interested[process]=TRUE;//表示感兴趣

turn =process;//设置标志

while(turn==process&&interested[other]==TRUE);//空语句

}

void leave_region(int process)

{

interested[process]=FALSE;

}

5.信号量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-prqKfDHi-1607345871930)(C:\Users\123\AppData\Roaming\Typora\typora-user-images\1603195016154.png)]

在缓冲区为空时,消费者不能再进行消费

在缓冲区为满时,生产者不能再进行生产

在一个线程进行生产或消费时,其余线程不能再进行生产或消费等操作,即保持线程间的同步

注意条件变量与互斥锁的顺序

​ 因此需要保持线程间的同步,即一个线程消费(或生产)完,其他线程才能进行竞争CPU,获得消费(或生产)的机会。对于这一点,可以使用条件变量进行线程间的同步:生产者线程在product之前,需要wait直至获取自己所需的信号量之后,才会进行product的操作;同样,对于消费者线程,在consume之前需要wait直到没有线程在访问共享区(缓冲区),再进行consume的操作,之后再解锁并唤醒其他可用阻塞线程。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-81HLnH8l-1607345871939)(C:\Users\123\AppData\Roaming\Typora\typora-user-images\1603195156901.png)]

假设缓冲区大小为10,生产者、消费者线程若干。生产者和消费者相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池中取走一个消息。

items代表缓冲区已经使用的资源数,spaces代表缓冲区可用资源数

mutex代表互斥锁

buf[10] 代表缓冲区,其内容类型为item

in、out代表第一个资源和最后一个资源 var items = 0, space = 10, mutex = 1;

var in = 0, out = 0;

item buf[10] = { NULL };

producer {

while( true ) {

wait( space ); // 等待缓冲区有空闲位置, 在使用PV操作时,条件变量需要在互斥锁之前

wait( mutex ); // 保证在product时不会有其他线程访问缓冲区

// product

buf.push( item, in ); // 将新资源放到buf[in]位置

in = ( in + 1 ) % 10;

signal( mutex ); // 唤醒的顺序可以不同

signal( items ); // 通知consumer缓冲区有资源可以取走

}

}

consumer {

while( true ) {

wait( items ); // 等待缓冲区有资源可以使用

wait( mutex ); // 保证在consume时不会有其他线程访问缓冲区

// consume

buf.pop( out ); // 将buf[out]位置的的资源取走

out = ( out + 1 ) % 10;

signal( mutex ); // 唤醒的顺序可以不同

signal( space ); // 通知缓冲区有空闲位置

}

}

6.调度

有多个进程同时竞争CPU,只要有两个或更多的进程处于就绪状态,这种情况就会发生。完成选择工作的这一部分程序称为调度程序,使用的算法称为调度算法。

6.1先来先服务:

6.2最短作业优先

6.3最短剩余时间优先

交互式系统中的调度:

轮转调度 优先级调度 多级调度

2.内存管理

1.地址空间

把物理地址暴露给进程会带来严重的问题:1.用户程序破坏操作系统,使得系统慢慢停止运行2.同时运行多个程序几乎不可能

多个程序同时处于内存中,不影响,需要 保护和重新定位

地址空间为程序创造了一种抽象的内存,地址空间是一个进程可用于寻址内存的一套地址集合。

基址寄存器与界限寄存器

交换技术:处理内存超载,将空闲进程存储在磁盘上。不运行时不会使用内存。分配额外内存

虚拟内存:每个进程有自己的进程空间,

标签:10,process,信号量,缓冲区,线程,内存,LINUX,进程

来源: https://blog.csdn.net/qq_39355828/article/details/110839777

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值