• 设备访问机制------阻塞与非阻塞


    阻塞操作: 执行设备操作时,若不能获得资源,则挂起进程直到满足可操作的条件后再进行操作,被挂起的进程进入休眠状态,从调度器的运行队列中移除,直到等待条件满足后再次运行。

    非阻塞操作: 执行设备操作时,若不能获得资源,并不挂起,它或者放弃,或者不停地查询,直到可进行操作为止。

    1. 阻塞了的进程要确保有一个地方能唤醒它,唤醒阻塞进程的操作一般是在中断里完成,因为硬件资源获得时一般伴随着硬件中断。

    2. 驱动中通过等待队列来实现阻塞进程的唤醒。

    3. 非阻塞程序实例:

    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <errno.h>
    
    char buffer[4096];
    
    int main(int argc, char **argv)
    {
        int delay = 1, n, m = 0;
    
        if (argc > 1)
            delay=atoi(argv[1]);
        fcntl(0, F_SETFL, fcntl(0,F_GETFL) | O_NONBLOCK); /* set stdin nonblock*/
        fcntl(1, F_SETFL, fcntl(1,F_GETFL) | O_NONBLOCK); /* set stdout nonblock*/
    
        while (1) {
            n = read(0, buffer, 4096);
            if (n >= 0)
                m = write(1, buffer, n);
            if ((n < 0 || m < 0) && (errno != EAGAIN))
                break;
            printf("coming here
    ");
            sleep(delay);
        }
        perror(n < 0 ? "stdin" : "stdout");
        exit(1);
    }
    View Code

     分析:通过 fcntl() 设置对标准输入及输出的访问为非阻塞访问。程序运行过程中,如果没有输入数据,则由于 read() 和 write() 调用不阻塞屏幕将打印 "coming here"。

    4. 阻塞程序实例:

    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <errno.h>
    
    char buffer[4096];
    
    int main(int argc, char **argv)
    {
        int delay = 1, n, m = 0;
    
        if (argc > 1)
            delay=atoi(argv[1]);
    //    fcntl(0, F_SETFL, fcntl(0,F_GETFL) | O_NONBLOCK); /* set stdin nonblock*/
    //    fcntl(1, F_SETFL, fcntl(1,F_GETFL) | O_NONBLOCK); /* set stdout nonblock*/
    
        while (1) {
            n = read(0, buffer, 4096);
            if (n >= 0)
                m = write(1, buffer, n);
            if ((n < 0 || m < 0) && (errno != EAGAIN))
                break;
            printf("coming here
    ");
            sleep(delay);
        }
        perror(n < 0 ? "stdin" : "stdout");
        exit(1);
    }
    View Code

     分析:去掉 fcntl() 设置非阻塞访问的语句,则是阻塞访问。程序运行过程中,由于 read() 的阻塞,导致每次输入完成后都在 read() 调用的地方暂停等待输入。

  • 相关阅读:
    Java中的事务
    ABCDE
    Android 防内存泄露handler
    自建应用新花样,菜鸟也会做应用
    软件測试之独步武林系列(一)
    刚在在win8.1下装了ubuntu12.04
    SVN 的一些操作
    [华为机试练习题]42.求二叉树的深度和宽度
    iOS_正則表達式
    在应用中更新App版本号
  • 原文地址:https://www.cnblogs.com/youngvoice/p/4840786.html
Copyright © 2020-2023  润新知