手把手教你实现Java进程同步实验—(1)实现进程同步的方法探究

举报
灰小猿 发表于 2021/12/29 13:39:23 2021/12/29
3.8k+ 0 0
【摘要】 Hello,你好呀,我是灰小猿,一个超会写bug的程序猿!身为一名浪漫的程序员,应该如何深入的实现进程同步嘞?今天就来和小猿一探究竟吧😇【文中程序员表情包大赏】!1 问题描述1.1 为什么要有进程同步在我们使用的操作系统中为什么要有进程同步机制?我们的计算机系统刚开始是单道批处理系统,意思就是同一时间段内只能运行一个程序,这个程序运行完,才能运行另一个程序,这样就会导致运行效率太低,系统中...

Hello,你好呀,我是灰小猿,一个超会写bug的程序猿!

身为一名浪漫的程序员,应该如何深入的实现进程同步嘞?今天就来和小猿一探究竟吧😇【文中程序员表情包大赏】!

1 问题描述

1.1 为什么要有进程同步

在我们使用的操作系统中为什么要有进程同步机制?我们的计算机系统刚开始是单道批处理系统,意思就是同一时间段内只能运行一个程序,这个程序运行完,才能运行另一个程序,这样就会导致运行效率太低,系统中的资源得不到充分的利用。这也是传统操作系统在进行业务处理的时候效率低下的主要原因,那么对于这种情况应该如何解决呢?这也是现在多道批处理系统出现的原因。

多道程序并发执行,这样大大提高了系统资源的利用率。但是这种系统就会产生一些问题,比如有的资源,比如显示器,cpu,同一时间肯定只能一个程序使用,多个程序肯定不能同时使用显示器,这就是互斥关系,另外,有的两个进程间存在这样的制约关系:A程序的输出是B程序的输入,这是同步关系,为了解决这些问题,我们引入了进程同步机制。通过实现进程同步机制,我们可以实现多个进程对于资源的同步访问,提高资源的使用效率。


1.2 进程同步的方法

对于实现进程同步,我们常用的方法就是实现信号量机制。常用的信号量机制有三种,分别是整型信号量,结构体型信号量和AND型信号量。那么这三种信号量机制具体指什么呢?接下来我对这三种信号量机制逐一进行介绍。

1.2.1 整型信号量

整型信号量是指用一个整数S来进行管理,这个整数S代表资源的数目,我们往往对资源的操作方式有两种,一种是使用,一种是释放。他们分别对应两个函数:wait和signal

wait函数的作用是首先会对资源S进行判断,看资源S可不可以用,如果不可以用,也就是S<=0,那么该进程会一直等下去,直到S成为一个正数,才会执行wait方法。然后S自减一次;而signal的意思则是使用完资源后释放资源,S自增一次。

Wait函数和signal函数的具体实现如下:

wait(S){
    while(S<=0);
    S--;
}

signal(S){
    S++}

整型信号量的缺点:

从上面的程序中,我们其实可以发现一个问题,就是当信号量S是小于0的时候,在wait函数中,程序会一直的死循环下去。这样进程就会处于一个“忙等”的状态。这也是使用整型信号量机制的不足之处,那么如果要解决“忙等”,就要让程序进行“让权等待”。也就是在进行无法使用资源的时候,释放处理机,避免长时间占用。

1.2.2 结构体型信号量

对于上面出现的问题,我们应该让哪个进程访问临界资源呢?这个时候结构体信号量就出现了,我们可以使用一个链表来解决这个问题。使用一个结构体来描述资源,这个结构体长这样:

typedef struct{
    int value;
    struct process_control_block *list;
}semaphore;

在这个结构体里边有两个变量,一个是value,用来记录资源的个数,第二个是指针,指向下一个要使用临界资源的进程。

通过使用结构体型信号量,wait和signal函数就进行了一些改进,如下这样:

wait(semaphore *S){
    S->value--;
    if(S->value<0)  block(S->list);
}

signal(semaphore *S){
    s->value++;
    if(S->value<=0)
      wakeup(S->list);
}

在程序中,S->value的初值表示系统中某类资源的数目,可称为资源信号量。

注:

S>0时:表示可供并发进程使用的资源数。

S<=0时:|S|表示因缺少该资源而自我阻塞的进程数。

在改进之后的wait函数中,首先会向操作系统申请资源,并且让资源数减一。如果资源分配完毕,那么就调用block原语将进程进行自我阻塞。

而在signal函数中,首先会释放资源,让资源数减一,之后进行判断,如果该信号量链表中仍有等待的进程被阻塞,那么就调用wakeup原语将其唤醒。

1.2.3 AND型信号量

AND型信号量是将进程在整个运行过程中的所有资源,一次性全部分配给进程,进程使用完后再一次性释放,只要一个进程尚未分配成功,其他所有为之分配的资源也不分配给它。也就说要么把它所请求的资源全部分配给进程,要么一个也不分配,这样的好处是可以很好的避免死锁现象。

使用该信号量机制时,wait和signal函数的实现如下:

wait(S1,S2,...,Sn)
{
    while(true)
    {
        if(Si>=1&&...&&Sn>=1)
        {
            for(i=1;i<n;i++)
            Si--;
            break;
        }
        else
        {
            place the process in the waiting queue associated with.....
            //如果没有申请到资源的话就挂到相应的阻塞队列里去
        }
    }
}

Ssignal(S1,S2,...Sn)
{
    while(true)
    {
        for(i=1;i<=n;i++)
        {
            Si++;
            remove all the process waiting in the queue associated with Si into the ready queue;
            //去后备队列里唤醒或移除因Si资源阻塞的进程
        }
    }
}

以上就是对三种信号量机制的作用和实现原理的说明。

觉得不错,记得🤞🏻一键三连🤞🏻哟!

下一篇和大家讲解如何使用信号量机制解决问题!

我是灰小猿,我们下期见!💘💘💘

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。