1、进程休眠

(1)进程有三种基本状态:就绪态、阻塞态、运行态。
<1>阻塞态:进程缺少除了CPU之外的某些资源,因此该进程不能被运行,被阻塞住了不能被CPU调度;
<2>就绪态:进程分配到了除CPU之外的所有资源,等待CPU调度执行;
<3>运行态:进程获得CPU资源,程序在CPU上运行;
(2)进程休眠:进程休眠就是进程因为缺少除了CPU之外的某些资源而进入阻塞态,会从调度器的运行队列中移走该进程,并把进程放到等待资源的队列中,直到分配到资源从而被唤醒,再次进入到就绪态,等待CPU调度;

2、进程休眠的注意事项

进程进入休眠是很容易的,只要申请不到资源都可能休眠,但是我们要保证进程以一种安全的方式进入休眠,也就是进程进入休眠后,
将来能被成功的唤醒;
(1)永远不要在原子上下文中进入休眠,原子操作本身就是要不可中断的一次性执行完;
(2)不能在拥有锁的时候进入休眠,否则可能会造成死锁;比如A进程在拥有自旋锁时进入休眠等待B进程唤醒,B进程需要先获得自旋锁进行一些操作才能唤醒A进程,
B进程等待A进程释放自旋锁,A进程等待B进程唤醒后才能释放锁,这就死锁了;
(3)拥有信号量时进程是可以进入休眠的,但是要非常注意:用于信号量而休眠的代码必须很短,并且还要确保拥有信号量斌不会阻塞最终唤醒我们自己的那个进程;
(4)进程被唤醒时,无法知道休眠了多长时间或者休眠期间都发生了什么事,所以在进程被唤醒后不要对状态进行任何假定,必须去检查我们等待的条件是否为真,因为
同时可能有别的进程因为等待同一资源而休眠,我们等待的资源可能被别的进程拿走;
(5)除非知道有其他进程会在其他地方唤醒我们,否则进程不能进入休眠;

3、进程的唤醒

(1)要唤醒进程,前提是要知道哪些进程进入休眠,是因为等待什么资源而进入休眠;
(2)在linux中,维护者一个称为等待队列的数据结构,相当于一个进程链表;将等待同一资源的进程放到同一个等待队列里,将来资源有空闲时就从
相应的等待队列中唤醒一个线程;

4、等待队列

4.1、初始化等待队列

 //静态初始化DECLARE_WAIT_QUEUE_HEAD(name) //动态方法wait_queue_head_t my_queue;init_waitqueue_head(&my_queue)

4.2、将进程添加到等待队列

/*
*wq:等待队列的头,就是上面初始化等待队列得到的;
*condition:条件表达式,当wake_up后,condition为真时,唤醒阻塞的进程
*timeout:超时时间
*/wait_event(wq, condition);    //进程进入休眠后不能被"ctrl+C"打断
wait_event_timeout(wq, condition, timeout);//进程进入休眠后超时返回
wait_event_interruptible(wq, condition);//进程进入休眠后能被"ctrl+C"打断

(1)举例:wait_event_interruptible(wq, havedata==1);
(2)分析:在进程中执行上面的代码,进程会被加入到wq等待队列中,直到将来被wake_up后,并且havedata==1时才能被唤醒;

4.3、唤醒等待队列中的进程

#define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL)#define wake_up_interruptible(x) __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL)

上面的两个唤醒函数和添加到等待队列的函数要对应使用,比如wake_up(x)对应wait_event(wq, condition);

5、驱动代码中等待队列的使用

//等待队列头
wait_queue_head_t rwq,wwq; //数据缓冲区标志位
int havedata = 0;static int hello_init(void)
{······//初始化两个等待队列init_waitqueue_head(&rwq); init_waitqueue_head(&wwq); ······
}static ssize_t hello_read (struct file *filep, char __user *buf, size_t size, loff_t *pos)
{int error;//此时如果没有准备好数据,则将进程休眠添加到rwq队列,等待唤醒wait_event_interruptible(rwq,havedata == 1);if(size > strlen(kbuf)){size = strlen(kbuf);}if(copy_to_user(buf,kbuf, size)){error = -EFAULT;return error;}//数据被读走,可以写数据havedata = 0;//唤醒需要写的进程wake_up_interruptible(&wwq);return size;
}static ssize_t hello_write (struct file *filep, const char __user *buf, size_t size, loff_t *pos)
{int error;//此时如果没有上次的数据没有被读走,则将进程休眠添加到wwq队列,等待唤醒wait_event_interruptible(wwq,havedata == 0);if(size > KMAX_LEN){size = KMAX_LEN;}memset(kbuf,0,sizeof(kbuf));if(copy_from_user(kbuf, buf, size)){error = -EFAULT;return error;}printk("%s\n",kbuf);//数据写入,可以读数据havedata = 1;//唤醒需要读的进程wake_up_interruptible(&rwq);return size;
}

上面是摘抄的部分驱动代码,在读写接口中实现休眠和唤醒;

进程的休眠与唤醒(等待队列)相关推荐

  1. Linux进程休眠和唤醒

    当进程以阻塞的方式通信,在得到结果前进程会挂起休眠. 为了将进程以一种安全的方式进入休眠,我们需要牢记两条规则: 一.永远不要在原子上下文中进入休眠. 二.进程休眠后,对环境一无所知.唤醒后,必须再次 ...

  2. 等待队列——休眠与唤醒

    内核中的休眠是通过等待队列来处理的.等待队列是一个由正在等待某个事件发生的进程组成的一个简单链表.在内核用wait_queue_head_t来表示. 定义: DECLARE_WAITQUEUE()(静 ...

  3. java 进程睡眠_Linux进程的睡眠和唤醒简析

    1.Linux进程的睡眠和唤醒 在Linux中,仅等待CPU时间的进程称为就绪进程,它们被放置在一个运行队列中,一个就绪进程的状 态标志位为TASK_RUNNING.一旦一个运行中的进程时间片用完, ...

  4. linux查看睡眠进程,关于 Linux 进程的睡眠和唤醒 ,来看这篇就够了~

    1 Linux 进程的睡眠和唤醒 在 Linux 中,仅等待 CPU 时间的进程称为就绪进程,它们被放置在一个运行队列中,一个就绪进程的状 态标志位为 TASK_RUNNING.一旦一个运行中的进程时 ...

  5. linux待机唤醒_Linux电源管理-休眠与唤醒

    1.休眠方式 在内核中,休眠方式有很多种,可以通过下面命令查看 # cat /sys/power/state //来得到内核支持哪几种休眠方式. 常用的休眠方式有freeze,standby, mem ...

  6. Linux Kernel and Android 休眠与唤醒(中文版)

    Linux Kernel and Android 休眠与唤醒(中文版) 四月 18th, 2010 0 Comments/1664 hits Table of Contents 简介 国际化 版本信息 ...

  7. Linux Kernel and Android休眠与唤醒

    版本信息 Linux Kernel: v2.6.28      Android: v2.0 对于休眠(suspend)的简单介绍 在Linux中,休眠主要分三个主要的步骤: 版本信息 Linux Ke ...

  8. 计算机休眠后无法唤醒出现蓝屏,win10系统下休眠后唤醒出现蓝屏0x000001c7如何解决...

    最近有win10系统用户反映说碰到这样一个问题,就是电脑进入休眠状态,想要唤醒的时候却出现了蓝屏,并提示0x000001c7错误代码,该怎么办呢,接下来给大家讲解一下win10系统下休眠后唤醒出现蓝屏 ...

  9. 标准linux休眠和唤醒机制分析

    标准linux休眠和唤醒机制分析 标准linux休眠和唤醒机制分析(一) 说明: 1. Based on linux2.6.32, only for mem(SDR) 2. 有兴趣请先参考阅读:电源管 ...

最新文章

  1. oracle 11g 的em启动不了
  2. Docker入门(三) - 搭建mysql
  3. SpringBoot数据缓存
  4. Java笔记-对CountDownLatch的理解(对比Qt中的QSemaphore)含实例
  5. R con not resolved of types
  6. 设置背景图片的两种方式,并解决手机端背景图片高度自适应问题
  7. Java代码题目:计算奖金和完全平方数
  8. codevs——1517 求一次函数解析式
  9. CSDN的markdown编辑器详细使用说明、语法快速索引手册
  10. Web服务器压力测试工具?
  11. 机器学习UCI数据库说明
  12. 小程序转发功能的实现(页面转发和按钮转发)
  13. apng java,免费的APNG、WebP格式转换工具-iSparta
  14. EEG中的EOG伪迹
  15. php地理位置打卡,定位地理位置PHP判断员工打卡签到经纬度是否在打卡之内
  16. 云计算机基地有辐射吗,孕妇离电脑多远没有辐射
  17. 微服务架构之服务调用
  18. R语言入门(15)_读取文件(read)
  19. 互联网公司级别的简单划分(小白总结)
  20. anaconda环境---ubuntu下重装

热门文章

  1. windows查看dll导出函数名
  2. 怎样通过几何画板绘制相似三角形
  3. 微信分享功能实现,兼容安卓和IOS
  4. 土木硕士转行互联网小结
  5. 微软CEO 鲍尔默的一天
  6. python中time是什么意思_python3时间中time是什么?怎么转换?
  7. 万字文详解Java泛型
  8. YunTable开发日记(16)-教程(0.9版RC)
  9. H5创建webApp保存到桌面。
  10. linux pid t 头文件_关于pid_t的理解