1. 程式人生 > >linux c單執行緒I/O超時處理

linux c單執行緒I/O超時處理

單執行緒I/O超時處理

UNIX下的I/O超時處理是一個很常見的問題, 它的通常做法是接收輸入(或傳送輸出)後立刻返回, 如果無輸入(或輸出)則n秒後定時返回.
一般情況下, 處理UNIX中I/O超時的方式有終端方式, 訊號跳轉方式和多路複用方式等三種. 本節設計一個定時I/O的例子, 它從檔案描述符0中讀取一個字元, 當有輸入時繼續, 或者3秒鐘後超時退出,並列印超時資訊.
(1) 終端I/O超時方式
利用ioctl函式, 設定檔案描述符對應的標準輸入檔案屬性為”接收輸入後立刻返回, 如無輸入則3秒後定時返回.
[[email protected] Unix_study]$ cat timeout1.c
#include <unistd.h>
#include <termio.h>
#include <fcntl.h>
int main()
{
        struct termio old, new;
        char c = 0;
        ioctl(0, TCGETA, &old);
        new = old;
        new.c_lflag &= ~ICANON;
        new.c_cc[VMIN] = 0;
        new.c_cc[VTIME] = 30;         // 設定檔案的超時時間為3秒
        ioctl(0, TCSETA, &new);
        if((read(0, &c, 1)) != 1)
                printf("timeout\n");
        else
                printf("\n%d\n", c);
        ioctl(0, TCSETA, &old);
        return 0;
}

[
[email protected]
Unix_study]$ make timeout1
cc     timeout1.c   -o timeout1
[[email protected] Unix_study]$ ./timeout1
x
120
[[email protected] Unix_study]$ ./timeout1
timeout
(2) 訊號與跳轉I/O超時方式
在read函式前呼叫setjmp儲存堆疊資料並使用alarm設定3秒定時.
[[email protected] Unix_study]$ cat timeout2.c
#include <setjmp.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int timeout = 0;
jmp_buf env;
void timefunc(int sig){
        timeout = 1;
        longjmp(env, 1);
}
int main()
{
        char c;
        signal(SIGALRM, timefunc);
        setjmp(env);
        if(timeout == 0){
                alarm(3);
                read(0, &c, 1);
                alarm(0);
                printf("%d\n", c);
        }
        else
                printf("timeout\n");
        return 0;

}

[
[email protected]
Unix_study]$ make timeout2
cc     timeout2.c   -o timeout2
[[email protected] Unix_study]$ ./timeout2
v                   // 需要按Enter健啟用輸入
118
[[email protected] Unix_study]$ ./timeout2
timeout
[[email protected] Unix_study]$
(3) 多路複用I/O超時方式
一個程序可能同時開啟多個檔案, UNIX中函式select可以同時監控多個檔案描述符的輸入輸出, 程序將一直阻塞, 直到超時或產生I/O為止, 此時函式返回, 通知程序讀取或傳送資料.
函式select的原型如下:
#include <sys/types.h>
#include <sys/times.h>
#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
FD_CLR(int fd, fd_set *fdset);    // 從fdset中刪去檔案描述符fd
FD_ISSET(int fd, fd_set *fdset);   // 查詢檔案描述符是否在fdset中
FD_SET(int fd, fd_set *fdset);     // 在fdset中插入檔案描述符fd
FD_ZERO(fd_set *fdset);        // 清空fdset
引數nfds是select監控的檔案描述符的時間, 一般為監控的最大描述符編號加1.
型別fd_set是檔案描述符集合, 其元素為監控的檔案描述符.
引數timeout是描述精確時間的timeval結構,它確定了函式的超時時間,有三種取值情況:
a) NULL. 函式永遠等待, 直到檔案描述符就緒.
b) 0. 函式不等待, 檢查檔案描述符狀態後立即返回.
c) 其他值. 函式等待檔案描述符就緒, 或者定時完成時返回.
函式select將返回檔案描述符集合中已準備好的檔案總個數. 函式select返回就緒檔案描述符數量後, 必須執行read等函式, 否則函式繼續返回就緒檔案數.

[
[email protected]
Unix_study]$ cat timeout3.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/times.h>
#include <sys/select.h>
int main()
{
        struct timeval timeout;
        fd_set readfds;
        int i;
        char c;
        timeout.tv_sec = 3;
        timeout.tv_usec = 0;
        FD_ZERO(&readfds);
        FD_SET(0, &readfds);
        i = select (1, &readfds, NULL, NULL, &timeout);
        if(i > 0){

                read(0, &c, 1);

                printf("%d\n", c);

        }
        else if(i == 0)
                printf("timeout\n");
        else
                printf("error\n");
        return 0;

}
[[email protected] Unix_study]$ make timeout3
cc     timeout3.c   -o timeout3
[[email protected] Unix_study]$ ./timeout3
x
120
[[email protected] Unix_study]$

[[email protected] Unix_study]$ ./timeout3

timeout

[[email protected] Unix_study]$

相關推薦

linux c執行I/O超時處理

單執行緒I/O超時處理 UNIX下的I/O超時處理是一個很常見的問題, 它的通常做法是接收輸入(或傳送輸出)後立刻返回, 如果無輸入(或輸出)則n秒後定時返回. 一般情況下, 處理UNIX中I/O超時的方式有終端方式, 訊號跳轉方式和多路複用方式等三種. 本節設計一個定時I

linux c執行開發

在開發多執行緒程式時,當建立的執行緒數量特別多的時候,就會遇到執行緒數量的瓶頸。 多執行緒設定 設定核心引數 kernel.threads-max kernel.threads-max 是 linux 系統允許建立的最大執行緒數,預設是 7767 修改 /etc/sysc

簡單的Linux C++多執行CLOCK(時鐘)類

剛剛加入CSDN部落格,初來乍到也不知道寫什麼,所以來分享一個自己以前學C++的時候寫的第一個類,一個關於時鐘的簡單的Linux多執行緒CLOCK(時鐘)類: /***********************************************

Linux c執行程式設計的4個例項

在主流的作業系統中,多工一般都提供了程序和執行緒兩種實現方式,程序享有獨立的程序空間,而執行緒相對於程序來說是一種更加輕量級的多工並行,多執行緒之間一般都是共享所在程序的記憶體空間的。   Linux也不例外,雖然從核心的角度來看,執行緒體現為一種對程序的"克隆"(clon

最簡單的實現Linux C++多執行的互斥訪問

#include <stdlib.h> #include <string.h> #include <iostream> #include <unistd.h> #include <errno.h> #include <pthrea

[Linux C程式設計]執行之間的同步與互斥

執行緒之間的同步與互斥 我們主要通過生產者與消費者之間的問題來體現執行緒之間的同步與互斥: 具體問題如下: 用執行緒實現:生產者與消費者: 一個緩衝區,兩個執行緒:生產者和消費者,一個放入快取一個從快

Linux C執行程式設計總結

執行緒的資料處理   和程序相比,執行緒的最大優點之一是資料的共享性,各個程序共享父程序處沿襲的資料段,可以方便的獲得、修改資料。但這也給多執行緒程式設計帶來了許多問題。我們必須當心有多個不同的程序訪問相同的變數。許多函式是不可重入的,即同時不能執行一個函式的多個拷貝(除非使用不同的資料段)。在函式中宣告的

Linux C執行程式設計】互斥鎖與條件變數

一、互斥鎖互斥量從本質上說就是一把鎖, 提供對共享資源的保護訪問。  1. 初始化:  在Linux下, 執行緒的互斥量資料型別是pthread_mutex_t. 在使用前, 要對它進行初始化:  對於靜態分配的互斥量, 可以把它設定為PTHREAD_MUTEX_INITIA

Linux C++多執行程式設計

1.介紹   相比程序,多執行緒是一種節儉的多工操作方式。在Linux系統下,啟動一個新的程序必須分配給它獨立的地址空間,建立眾多的資料表來維護它的程式碼段、堆疊段和資料段。而執行一個程序中的多個執行緒,它們彼此之間使用相同的地址空間,共享大部分資料,啟動一個

關於linux c執行排程執行順序

最近在學習linux 下c語言的多執行緒排程,在博主李亞超的文章Linux C 多執行緒執行順序問題(原連結:http://blog.csdn.net/harry_lyc/article/details/6055734#reply)一文中的下面回覆有人探討到執行緒之間是通過

基於Linux/C++簡單執行池的實現

我們知道Java語言對於多執行緒的支援十分豐富,JDK本身提供了很多效能優良的庫,包括ThreadPoolExecutor和ScheduleThreadPoolExecutor等。C++11中的STL也提供了std:thread(然而我還沒有看,這裡先佔個坑)還有很多第三方庫

C# 執行和多執行下的例模式的實現

該單例模式是執行緒不安全的,只能在單執行緒下執行,在多執行緒中如果被兩個執行緒同時呼叫Instance屬性時,此時兩個執行緒判斷 if (_instance==null)時都會返回true,就會建立兩個例項。public class Singleton{ /// <

LInux C++多執行程式設計基礎(彙總)

1. 前言    本次來寫一篇關於C++多執行緒的基本使用。前面有一篇是互斥鎖的入門,學了兩天,做一下總結。2. 多執行緒    (1) 建立多執行緒的表示pthread_t:/* Thread identifiers. The structure of the attri

基於Linux C執行軟體框架實現

之前寫過一篇基於C語言連結串列實現的工作任務註冊與執行,連結如下:https://blog.csdn.net/morixinguan/article/details/77986553後面使用它演變成為了另外一個框架,也就是多執行緒,當時的設計思路主要是為了服務測試程式。搞過R

Node-執行、事件驅動、非阻塞I/O

Nodejs既然這麼流行就肯定有它的博大精深之處,自然不是我這還沒入門的小白可以掌握的,我就簡單說一下目前自己的理解程度。 一、單執行緒、非阻塞I/O、事件驅動 這是nodejs的三個特點。 單執行緒 Nodejs是單執行緒,和多執行緒相比: 優點:可以避免系統分配多執行緒以及執行

node.js的非同步I/O、事件驅動、執行

nodejs的特點總共有以下幾點 非同步I/O(非阻塞I/O) 事件驅動 單執行緒 擅長I/O密集型,不擅長CPU密集型 高併發 下面是一道很經典的面試題,描述了node的整體執行機制,相信很多人都碰到了。這道題背後的原理就是nodejs程式碼執行順序 setTimeout(function()

c++ 網絡編程(四)TCP/IP LINUX/windows下 socket 基於I/O復用的服務器端代碼 解決多進程服務端創建進程資源浪費問題

linux系統中 cin 通過 sel print 大小 查看 服務 集合 原文作者:aircraft 原文鏈接:https://www.cnblogs.com/DOMLX/p/9613861.html 好了,繼上一篇說到多進程服務端也是有缺點的,每創建一個

C#】C#執行_I/O限制的非同步操作

目錄結構: contents structure [+] 為什麼需要非同步IO操作 C#的非同步函式 async和await的使用 非同步函式的狀態機 非同步函式如何轉化為狀態機 如何擴充套件非

Linux/Windows下C++設定執行名字方便多執行除錯

C++多執行緒程式設計,除錯是一個大問題,原因之一就是,執行緒名字繼承了父程序的名字,因此導致同一段程式碼的不同執行緒名字一樣;而且還會導致執行緒的名字怪怪的,不好看。 因此,如果在程式碼中可以設定執行緒的名字就好了,這樣在除錯中就可以看到期望的執行緒名字,這樣便於除錯。 由於編

C# 多執行學習系列四之取消、超時執行操作

1、簡介 雖然ThreadPool、Thread能開啟子執行緒將一些任務交給子執行緒去承擔,但是很多時候,因為某種原因,比如子執行緒發生異常、或者子執行緒的業務邏輯不符合我們的預期,那麼這個時候我們必須關閉它,而不是讓它繼續執行,消耗資源.讓CPU不在把時間和資源花在沒有意義的程式碼上.