中文字幕 另类精品,亚洲欧美一区二区蜜桃,日本在线精品视频免费,孩交精品乱子片免费

<sup id="3hn2b"></sup>

    1. <sub id="3hn2b"><ol id="3hn2b"></ol></sub><legend id="3hn2b"></legend>

      1. <xmp id="3hn2b"></xmp>

      2. 新聞中心

        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.antipu.com.cn/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); //進(jìn)入寫等待隊列頭

          /* 等待FIFO非滿 */

          if (dev->current_len == GLOBALFIFO_SIZE)

          {

          if (filp->f_flags &O_NONBLOCK)

          //如果是非阻塞訪問

          {

          ret = - EAGAIN;

          goto out;

          }

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

          up(&dev->sem);

          schedule(); //調(diào)度其他進(jìn)程執(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ū)動機(jī)制

          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");

          }

          }

          當(dāng)我們加載完驅(qū)動并創(chuàng)建完設(shè)備節(jié)點后,運行上述程序,每當(dāng)通過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)閉