iis服务器助手广告广告
返回顶部
首页 > 资讯 > 操作系统 >Linux中进程怎么设置睡眠和唤醒
  • 426
分享到

Linux中进程怎么设置睡眠和唤醒

2023-06-16 13:06:22 426人浏览 薄情痞子
摘要

这期内容当中小编将会给大家带来有关linux中进程怎么设置睡眠和唤醒,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Linux 中的进程睡眠状态分类一种是可中断的睡眠状态,其状态标志位TASK_INTERR

这期内容当中小编将会给大家带来有关linux中进程怎么设置睡眠和唤醒,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

Linux 中的进程睡眠状态分类

一种是可中断的睡眠状态,其状态标志位TASK_INTERRUPTIBLE;

另一种是不可中断  的睡眠状态,其状态标志位为TASK_UNINTERRUPTIBLE。可中断的睡眠状态的进程会睡眠直到某个条件变为真,比如说产生一个硬件中断、释放  进程正在等待的系统资源或是传递一个信号都可以是唤醒进程的条件。不可中断睡眠状态与可中断睡眠状态类似,但是它有一个例外,那就是把信号传递到这种睡眠  状态的进程不能改变它的状态,也就是说它不响应信号的唤醒。不可中断睡眠状态一般较少用到,但在一些特定情况下这种状态还是很有用的,比如说:进程必须等  待,不能被中断,直到某个特定的事件发生。

在现代的Linux操作系统中,进程一般都是用调用schedule()的方法进入睡眠状态的,下面的代码演

示了如何让正在运行的进程进入睡眠状态。

sleeping_task = current;  set_current_state(TASK_INTERRUPTIBLE);  schedule();  func1();  

在***个语句中,程序存储了一份进程结构指针sleeping_task,current 是一个宏,它指向正在执行

的进程结构。set_current_state()将该进程的状态从执行状态TASK_RUNNING 变成睡眠状态

TASK_INTERRUPTIBLE。 如果schedule()是被一个状态为TASK_RUNNING  的进程调度,那么schedule()将调度另外一个进程占用CPU;如果schedule()是被一个状态为TASK_INTERRUPTIBLE  或TASK_UNINTERRUPTIBLE  的进程调度,那么还有一个附加的步骤将被执行:当前执行的进程在另外一个进程被调度之前会被从运行队列中移出,这将导致正在运行的那个进程进入睡眠,因为  它已经不在运行队列中了。

我们可以使用下面的这个函数将刚才那个进入睡眠的进程唤醒。

wake_up_process(sleeping_task);

在调用了wake_up_process()以后,这个睡眠进程的状态会被设置为TASK_RUNNING,而且调度器

会把它加入到运行队列中去。当然,这个进程只有在下次被调度器调度到的时候才能真正地投入运行。

无效唤醒

几乎在所有的情况下,进程都会在检查了某些条件之后,发现条件不满足才进入睡眠。可是有的时候

进程却会在  判定条件为真后开始睡眠,如果这样的话进程就会***期地休眠下去,这就是所谓的无效唤醒问题。在操作系统中,当多个进程都企图对共享数据进行某种处理,而  ***的结果又取决于进程运行的顺序时,就会发生竞争条件,这是操作系统中一个典型的问题,无效唤醒恰恰就是由于竞争条件导致的。

设想有两个进程A 和B,A 进程正在处理一个链表,它需要检查这个链表是否为空,如果不空就对链

表里面的数据进行一些操作,同时B进程也在往这个链表添加节点。当这个链表是空的时候,由于无数据可操作,这时A进程就进入睡眠,当B进程向链表里面添加了节点之后它就唤醒A  进程,其代码如下:

A进程:

spin_lock(&list_lock);  if(list_empty(&list_head)) {    spin_unlock(&list_lock);    set_current_state(TASK_INTERRUPTIBLE);    schedule();    spin_lock(&list_lock);  }    spin_unlock(&list_lock);

B进程:

spin_lock(&list_lock);  list_add_tail(&list_head, new_node);  spin_unlock(&list_lock);  wake_up_process(processa_task);

这里会出现一个问题,假如当A进程执行到第3行后第4行前的时候,B进程被另外一个处理器调度

投 入运行。在这个时间片内,B进程执行完了它所有的指令,因此它试图唤醒A进程,而此时的A进程还没有进入睡眠,所以唤醒操作无效。在这之后,A  进程继续执行,它会错误地认为这个时候链表仍然是空的,于是将自己的状态设置为TASK_INTERRUPTIBLE然后调用schedule()进入睡  眠。由于错过了B进程唤醒,它将会***期的睡眠下去,这就是无效唤醒问题,因为即使链表中有数据需要处理,A 进程也还是睡眠了。

避免无效唤醒

如何避免无效唤醒问题呢?我们发现无效唤醒主要发生在检查条件之后和进程状态被设置为睡眠状

态之前, 本来B进程的wake_up_process()提供了一次将A进程状态置为TASK_RUNNING  的机会,可惜这个时候A进程的状态仍然是TASK_RUNNING,所以wake_up_process()将A进程状态从睡眠状态转变为运行状态的努力  没有起到预期的作用。要解决这个问题,必须使用一种保障机制使得判断链表为空和设置进程状态为睡眠状态成为一个不可分割的步骤才行,也就是必须消除竞争条  件产生的根源,这样在这之后出现的wake_up_process ()就可以起到唤醒状态是睡眠状态的进程的作用了。

找到了原因后,重新设计一下A进程的代码结构,就可以避免上面例子中的无效唤醒问题了。

A进程:

set_current_state(TASK_INTERRUPTIBLE);  spin_lock(&list_lock);  if(list_empty(&list_head)) {  spin_unlock(&list_lock);  schedule();  spin_lock(&list_lock);  }  set_current_state(TASK_RUNNING);     spin_unlock(&list_lock);

可以看到,这段代码在测试条件之前就将当前执行进程状态转设置成TASK_INTERRUPTIBLE了,并且在链表不为空的情况下又将自己置为TASK_RUNNING状态。这样一来如果B进程在A进程进程检查

了链表为空以后调用wake_up_process(),那么A进程的状态就会自动由原来TASK_INTERRUPTIBLE

变成TASK_RUNNING,此后即使进程又调用了schedule(),由于它现在的状态是TASK_RUNNING,所以仍然不会被从运行队列中移出,因而不会错误的进入睡眠,当然也就避免了无效唤醒问题。

Linux内核的例子

在Linux操作系统中,内核的稳定性至关重要,为了避免在Linux操作系统内核中出现无效唤醒问题,

Linux内核在需要进程睡眠的时候应该使用类似如下的操作:

  DECLARE_WAITQUEUE(wait,current);  add_wait_queue(q, &wait);  set_current_state(TASK_INTERRUPTIBLE);    while(!condition)   schedule();  set_current_state(TASK_RUNNING);  remove_wait_queue(q, &wait);

上面的操作,使得进程通过下面的一系列步骤安全地将自己加入到一个等待队列中进行睡眠:首先调

用DECLARE_WAITQUEUE ()创建一个等待队列的项,然后调用add_wait_queue()把自己加入到等待队列中,并且将进程的状态设置为  TASK_INTERRUPTIBLE  或者TASK_INTERRUPTIBLE。然后循环检查条件是否为真:如果是的话就没有必要睡眠,如果条件不为真,就调用schedule()。当进程  检查的条件满足后,进程又将自己设置为TASK_RUNNING 并调用remove_wait_queue()将自己移出等待队列。

从上面可以看到,Linux的内核代码维护者也是在进程检查条件之前就设置进程的状态为睡眠状态,

然后才循环检查条件。如果在进程开始睡眠之前条件就已经达成了,那么循环会退出并用set_current_state()将自己的状态设置为就绪,这样同样保证了进程不会存在错误的进入睡眠的倾向,当然也就不会导致出现无效唤醒问题。

下面让我们用linux 内核中的实例来看看Linux  内核是如何避免无效睡眠的,这段代码出自Linux2.6的内核(linux-2.6.11/kernel/sched.c: 4254):

  set_current_state(TASK_INTERRUPTIBLE);  while (!kthread_should_stop()) {  schedule();  set_current_state(TASK_INTERRUPTIBLE);  }  __set_current_state(TASK_RUNNING);  return 0;

上面的这些代码属于迁移服务线程migration_thread,这个线程不断地检查kthread_should_stop(),

直 到kthread_should_stop()返回1它才可以退出循环,也就是说只要kthread_should_stop()返回0该进程就会一直睡  眠。从代码中我们可以看出,检查kthread_should_stop()确实是在进程的状态被置为TASK_INTERRUPTIBLE后才开始执行  的。因此,如果在条件检查之后但是在schedule()之前有其他进程试图唤醒它,那么该进程的唤醒操作不会失效。

上述就是小编为大家分享的Linux中进程怎么设置睡眠和唤醒了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注编程网操作系统频道。

--结束END--

本文标题: Linux中进程怎么设置睡眠和唤醒

本文链接: https://www.lsjlt.com/news/283720.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Linux中进程怎么设置睡眠和唤醒
    这期内容当中小编将会给大家带来有关Linux中进程怎么设置睡眠和唤醒,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Linux 中的进程睡眠状态分类一种是可中断的睡眠状态,其状态标志位TASK_INTERR...
    99+
    2023-06-16
  • Linux进程的睡眠和唤醒方法是什么
    本文小编为大家详细介绍“Linux进程的睡眠和唤醒方法是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Linux进程的睡眠和唤醒方法是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。在Linux中,仅等待...
    99+
    2023-06-27
  • win11睡眠唤醒密码如何设置
    这篇文章主要介绍“win11睡眠唤醒密码如何设置”,在日常操作中,相信很多人在win11睡眠唤醒密码如何设置问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”win11睡眠唤醒密码如何设置”的疑惑有所帮助!接下来...
    99+
    2023-07-02
  • win10睡眠唤醒就蓝屏怎么解决
    本文小编为大家详细介绍“win10睡眠唤醒就蓝屏怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“win10睡眠唤醒就蓝屏怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。win10睡眠唤醒就蓝屏的解决...
    99+
    2023-07-01
  • 在win8系统中怎么设置睡眠唤醒需要输入密码
      我的系统是wind   1.点击超级按钮的“设置”选项,如下图:   2.点击“设置”选项中下方的“更改电脑设置”,如下图:   3.在&l...
    99+
    2023-06-04
    win8 睡眠 唤醒 系统 密码
  • Windows 7睡眠唤醒后黑屏怎么办?
    最近好多网友反映电脑在睡眠状态唤醒时进入黑屏状态,无法正常进入屏幕,系统也重新安装了还是没有反应,下面小编就为大家分享下碰到此种情况具体解决办法。希望对大家有所帮助。 1、右键点击桌面“计算机”,...
    99+
    2023-06-15
    win8.1睡眠后唤醒黑屏 win7睡眠后唤醒黑屏 电脑睡眠后唤 黑屏 Windows 7睡眠
  • win101909睡眠无法唤醒屏幕怎么解决
    本文小编为大家详细介绍“win101909睡眠无法唤醒屏幕怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“win101909睡眠无法唤醒屏幕怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。方法一: ...
    99+
    2023-07-01
  • win7睡眠唤醒后电脑黑屏怎么办
    这篇文章主要介绍“win7睡眠唤醒后电脑黑屏怎么办”,在日常操作中,相信很多人在win7睡眠唤醒后电脑黑屏怎么办问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”win7睡眠唤醒后电脑黑屏怎么办”的疑惑有所帮助!...
    99+
    2023-06-28
  • win7系统自动睡眠无法唤醒怎么办
    这篇文章给大家分享的是有关win7系统自动睡眠无法唤醒怎么办的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。点击开始菜单 - 控制面板,在打开的控制面板中点击打开“硬件和声音”。在硬件和声音界面中,点击打开“电源选...
    99+
    2023-06-28
  • win10电源和睡眠怎么设置
    本篇内容主要讲解“win10电源和睡眠怎么设置”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“win10电源和睡眠怎么设置”吧!win10电源和睡眠一般都设置多久最好详细介绍:如果是想要电脑保养的...
    99+
    2023-07-02
  • win7系统长时间无操作进入睡眠模式后禁止鼠标和键盘唤醒
      在win7系统中,在开始菜单的关机选项有一个睡眠。在你长时间没有操作的情况下,电脑就会进入睡眠模式,正常默认系统设置的情况下,如果你碰到鼠标和键盘系统就会解除睡眠模式被唤醒,如果你不喜欢这样,要怎么办呢   睡眠模式...
    99+
    2023-06-08
    win7 睡眠模式 唤醒 睡眠 操作 时间 模式 鼠标
  • win10系统怎么设置睡眠时间
    这篇文章将为大家详细讲解有关win10系统怎么设置睡眠时间,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、右键点击桌面空白处,在菜单中选择“显示设置”。二、在弹出的窗口中,点击左侧的“电源和睡眠”。三、...
    99+
    2023-06-28
  • win11小娜怎么设置语音唤醒
    本篇内容介绍了“win11小娜怎么设置语音唤醒”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!win11小娜可不可以语音唤醒:答:可以语音唤醒...
    99+
    2023-07-01
  • 怎样设置Windows Vista系统的休眠和睡眠时间
      一、使用系统自带的电源管理更改Windows Vista的睡眠设置   点击开始-控制面板-电源选项,如图:   选择电源选项后,弹出如图窗口:   在左侧任务窗格中选择“更改计算机的睡眠时间&rdq...
    99+
    2023-05-29
    Vista 休眠 睡眠 时间 Windows 系统
  • 小编告诉你win7电脑睡眠后老是立即又自动唤醒怎么回事
    当我们需要短暂离开电脑的时候可以设置电脑进入睡眠,不过最近就有用户遇到win7电脑睡眠后老是立即又自动唤醒的情况,那么win7电脑睡眠后老是立即又自动唤醒怎么回事呢?今天小编就来告诉大家原因以及win7电脑睡眠后老是立即又自动唤醒怎么办。下...
    99+
    2023-07-18
  • win7怎么设置睡眠继续下载
    这篇文章主要介绍了win7怎么设置睡眠继续下载,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。使用组合键“Win+R”,打开运行输入框,并在输入栏内输入“regedit”按下回...
    99+
    2023-06-28
  • Node.js中怎么实现线程睡眠
    Node.js中怎么实现线程睡眠,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一:糟糕的 “循环空转”下面这段代码是糟糕的,Node.js...
    99+
    2024-04-02
  • windows10怎么设置唤醒必须密码windows10怎么设置唤醒必须密码方式详细介绍
    windows10怎么设置唤醒必须密码这些问题素来是很多用户想知道的,用户们使用win10的情况下毫无疑问遇到过系统软件休眠睡眠的状况,一般这样子是立即死机休眠状态,因此要是要想设置休眠后开启必须密码才可以进入系统要怎么办呢,这儿为大伙儿带...
    99+
    2023-07-17
  • linux怎么设置不休眠
    要在Linux中设置不休眠,您可以按照以下步骤进行操作:1. 使用命令行或终端打开`/etc/systemd/logind.conf...
    99+
    2023-09-16
    linux
  • Win7系统怎么设置禁止鼠标唤醒计算机?
    我们在使用Windows 7的时候,尤其是笔记本电脑,在不用的时候,轻轻合上上盖,计算机就进入了休眠模式,即防止了计算机被乱用,也有效节省了电能。但是在Windows 7的默认设置下,常常会出现偶尔触碰一下鼠标就被唤醒的...
    99+
    2023-06-15
    win7鼠标键盘无法唤醒 win7系统待机无法唤醒 win7睡眠鼠标唤 鼠标 系统 计算机 Win7
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作