linux的同步和異步

1.同步

      筆者在本文只分析poll同步機制,首先看poll函數的用法:

       #include <poll.h>
       int poll(struct pollfd fds[], nfds_t nfds, int timeout);

      struct pollfd {
      int fd; /*文件描述符*/
      short events; /* 需要測試的事件 */
      short revents; /* 實際發生的事件,也就是返回結果 */
       };

功能:

查詢數組fds中的fd是否發生了events事件,若發生了events事件,poll立即返回,不阻塞;若沒有fd發生events事件,則poll阻塞,經過timeout時間後被喚醒。

參數:

nfds指示fds數組的項數,timeout指示poll函數的超時時間(超過時間,則調用poll函數的進程被喚醒),timeout=0,進程不阻塞;timeout<0,進程阻塞到事件發生爲止。例子如下:
        ret = poll(fds, 1, 5000);
        if (ret == 0)  //fds中沒有可讀寫的設備文件
        {
            do something;
        }
        else             //fds中有可讀寫的設備文件
        {
            do otherthing;
        }

返回值:

>0,發生了指定events的fd的數量;=0,沒有fd發生了events;-1,調用poll失敗

原理:

poll函數最終會調用每個fd對應的xxx_poll函數(屬於驅動程序),xxx_poll調用poll_wait()將進程掛到等待隊列(不會阻塞),xxx_poll()函數返回一個mask給poll(),該mask裏面包含了特定的events,xxx_poll()決定哪種情況下使得mask裏面含有POLLIN、POLLRDNORM等events 。poll()函數調用schedule_timeout()進行休眠。例子如下:

static unsigned xxx_poll(struct file *file, poll_table *wait)
{
    unsigned int mask = 0;
    poll_wait(file, &button_waitq, wait); // 不休眠

    if (condition)
        mask |= POLLIN | POLLRDNORM;//條件成立,則設備文件可讀,返回表示可讀的mask

    return mask;
}

2.異步

原理:
          由文件(驅動程序)嚮應用程序發送信號,應用程序再調用信號函數。

應用層:

         首先需要應用程序綁定一個信號函數,當收到某個信號後,執行該函數;然後需要將該進程和某個設備文件綁定,這樣設備文件可讀寫時,才知道給那個進程發信號。例子如下:
    signal(SIGIO, my_signal);.//綁定信號函數

    fcntl(fd, F_SETOWN, getpid());//綁定進程和設備文件
    
    Oflags = fcntl(fd, F_GETFL); 
    
    fcntl(fd, F_SETFL, Oflags | FASYNC);//給設備文件添加異步通知標識(調用驅動程序裏的xxx_fasync()函數)
   
          三個步驟執行後,設備文件就可以向進程發送信號了。

驅動層:

        在設備驅動程序裏,實現向進程發送信號的功能。
         xxx_fasync(),調用fasync_helper()函數,初始化一個結構體
         kill_fasync(),向進程發送信號。

        static int  xxx_fasync (int fd, struct file *filp, int on)
       {
            return fasync_helper (fd, filp, on, &button_async);//初始化fasync_struct結構體,該結構體在向進程發送信號時用到
        }

         kill_fasync (&button_async, SIGIO, POLL_IN);  //設備文件可讀寫時,調用該函數,向進程發送信號

3.總結

我們在讀寫設備文件時,可以採用同步或異步機制,同步機制下,需要我們的應用程序自己不斷去查詢設備文件是否可讀寫,屬於主動出擊;而採用異步機制時,應用程序是被動接受信號,當設備文件可讀寫時,由設備驅動程序給應用程序發信號,應用程序然後纔去讀寫設備文件,屬於被動接受。

同步和異步實現,都是靠對應的設備驅動程序。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章