• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > Linux內(nèi)核開發(fā)之異步通知與異步I/O(二)

    Linux內(nèi)核開發(fā)之異步通知與異步I/O(二)

    作者: 時間:2016-12-09 來源:網(wǎng)絡(luò) 收藏

      “曾經(jīng)有一份真摯的愛情擺在面前,我卻不懂珍惜;曾經(jīng)有一個承諾,我卻倍感珍惜,今天一定要好好講講..”

    本文引用地址:http://www.czjhyjcfj.com/article/201612/341380.htm

      講講啥,講講上節(jié)說的那個異步通知的例子唄,大家喜歡看代碼,咋們就先上代碼:

      struct globalfifo_dev

      {

      struct cdev cdev; /*cdev結(jié)構(gòu)體*/

      unsigned int current_len; /*fifo有效數(shù)據(jù)長度*/

      unsigned char mem[GLOBALFIFO_SIZE]; /*全局內(nèi)存*/

      struct semaphore sem; /*并發(fā)控制用的信號量*/

      wait_queue_head_t r_wait; /*阻塞讀用的等待隊列頭*/

      wait_queue_head_t w_wait; /*阻塞寫用的等待隊列頭*/

      struct fasync_struct *async_queue; /* 異步結(jié)構(gòu)體指針,用于讀 */

      };

      /*文件釋放函數(shù)*/

      int globalfifo_release(struct inode *inode, struct file *filp)

      {

      /* 將文件從異步通知列表中刪除 */

      globalmem_fasync( - 1, filp, 0);

      return 0;

      }

      static int globalfifo_fasync(int fd, struct file *filp, int mode)

      {

      struct globalfifo_dev *dev = filp->private_data;

      return fasync_helper(fd, filp, mode, &dev->async_queue);

      }

      /*globalfifo寫操作*/

      static ssize_t globalfifo_write(struct file *filp, const char __user *buf,

      size_t count, loff_t *ppos)

      {

      struct globalfifo_dev *dev = filp->private_data; //獲得設(shè)備結(jié)構(gòu)體指針

      int ret;

      DECLARE_WAITQUEUE(wait, current); //定義等待隊列

      down(&dev->sem); //獲取信號量

      add_wait_queue(&dev->w_wait, &wait); //進入寫等待隊列頭

      /* 等待FIFO非滿 */

      if (dev->current_len == GLOBALFIFO_SIZE)

      {

      if (filp->f_flags &O_NONBLOCK)

      //如果是非阻塞訪問

      {

      ret = - EAGAIN;

      goto out;

      }

      __set_current_state(TASK_INTERRUPTIBLE); //改變進程狀態(tài)為睡眠

      up(&dev->sem);

      schedule(); //調(diào)度其他進程執(zhí)行

      if (signal_pending(current))

      //如果是因為信號喚醒

      {

      ret = - ERESTARTSYS;

      goto out2;

      }

      down(&dev->sem); //獲得信號量

      }

      /*從用戶空間拷貝到內(nèi)核空間*/

      if (count > GLOBALFIFO_SIZE - dev->current_len)

      count = GLOBALFIFO_SIZE - dev->current_len;

      if (copy_from_user(dev->mem + dev->current_len, buf, count))

      {

      ret = - EFAULT;

      goto out;

      }

      else

      {

      dev->current_len += count;

      printk(KERN_INFO "written %d bytes(s),current_len:%dn", count, dev

      ->current_len);

      wake_up_interruptible(&dev->r_wait); //喚醒讀等待隊列

      /* 產(chǎn)生異步讀信號 */

      if (dev->async_queue)

      kill_fasync(&dev->async_queue, SIGIO, POLL_IN);

      ret = count;

      }

      out: up(&dev->sem); //釋放信號量

      out2:remove_wait_queue(&dev->w_wait, &wait); //從附屬的等待隊列頭移除

      set_current_state(TASK_RUNNING);

      return ret;

      }

      下面再給出測試程序:

      #include ...

      //接收到異步讀信號的動作

      void input_handler(int signum)

      {

      printf("Receive a signal from globalfifo,signalnum:%dn",signum);

      }

      int main()

      {

      int fd, oflags;

      fd = open("/dev/globalfifo", O_RDWR, S_IRUSR | S_IWUSR);

      if (fd != - 1)

      {

      //啟動信號驅(qū)動機制

      signal(SIGIO, input_handler); //讓input_handler()處理SIGIO信號

      fcntl(fd, F_SETOWN, getpid());

      oflags = fcntl(fd, F_GETFL);

      fcntl(fd, F_SETFL, oflags | FASYNC);

      while(1)

      {

      sleep(100);

      }

      }

      else

      {

      printf("device open failuren");

      }

      }

      當我們加載完驅(qū)動并創(chuàng)建完設(shè)備節(jié)點后,運行上述程序,每當通過echo向/dev/globalfilfo寫入新的數(shù)據(jù)后,input_handler將會被調(diào)用。如下所示:

      echo 0>/dev/globalfifo

      receive a signal from globalfifo ,signalnum:29

      echo 0>/dev/globalfifo

      receive a signal from globalfifo ,signalnum:29

      echo 0>/dev/globalfifo

      receive a signal from globalfifo ,signalnum:29

      通過上邊實際的例子,小王,明白了吧,我的承諾也兌現(xiàn)了,下次咱們可要開始更高級的東西了..



    關(guān)鍵詞: Linux 異步I/O

    評論


    相關(guān)推薦

    技術(shù)專區(qū)

    關(guān)閉
    主站蜘蛛池模板: 武强县| 比如县| 会昌县| 浦城县| 鸡东县| 毕节市| 邯郸市| 长兴县| 长泰县| 梅河口市| 都匀市| 星座| 井研县| 寿光市| 科尔| 黄平县| 青神县| 屯门区| 武陟县| 玛曲县| 关岭| 濮阳市| 桐庐县| 乐至县| 维西| 日照市| 织金县| 枞阳县| 桑植县| 白银市| 独山县| 勐海县| 格尔木市| 富阳市| 兴安县| 宝清县| 廊坊市| 宁城县| 彩票| 广水市| 元阳县|