日本a√视频在线,久久青青亚洲国产,亚洲一区欧美二区,免费g片在线观看网站

        <style id="k3y6c"><u id="k3y6c"></u></style>
        <s id="k3y6c"></s>
        <mark id="k3y6c"></mark>
          
          

          <mark id="k3y6c"></mark>

          新聞中心

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

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

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

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

          本文引用地址:http://yuyingmama.com.cn/article/201612/341380.htm

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

            struct globalfifo_dev

            {

            struct cdev cdev; /*cdev結構體*/

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

            unsigned char mem[GLOBALFIFO_SIZE]; /*全局內存*/

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

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

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

            struct fasync_struct *async_queue; /* 異步結構體指針,用于讀 */

            };

            /*文件釋放函數(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; //獲得設備結構體指針

            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(); //調度其他進程執(zhí)行

            if (signal_pending(current))

            //如果是因為信號喚醒

            {

            ret = - ERESTARTSYS;

            goto out2;

            }

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

            }

            /*從用戶空間拷貝到內核空間*/

            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); //喚醒讀等待隊列

            /* 產生異步讀信號 */

            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)

            {

            //啟動信號驅動機制

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

            }

            }

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

            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)了,下次咱們可要開始更高級的東西了..



          關鍵詞: Linux 異步I/O

          評論


          相關推薦

          技術專區(qū)

          關閉