国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

驅(qū)動(dòng)開發(fā),IO多路復(fù)用實(shí)現(xiàn)過程,epoll方式

這篇具有很好參考價(jià)值的文章主要介紹了驅(qū)動(dòng)開發(fā),IO多路復(fù)用實(shí)現(xiàn)過程,epoll方式。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1.框架圖

驅(qū)動(dòng)開發(fā),IO多路復(fù)用實(shí)現(xiàn)過程,epoll方式,驅(qū)動(dòng)開發(fā),驅(qū)動(dòng)開發(fā),stm32,c語言,嵌入式硬件

被稱為當(dāng)前時(shí)代最好用的io多路復(fù)用方式;

核心操作:一棵樹(紅黑樹)、一張表(內(nèi)核鏈表)以及三個(gè)接口;

?思想:(fd代表文件描述符)

????????epoll要把檢測(cè)的事件fd掛載到內(nèi)核空間紅黑樹上,遍歷紅黑樹,調(diào)用每個(gè)fd對(duì)應(yīng)的操作方法,找到發(fā)生事件的fd,如果沒有發(fā)生事件的fd,進(jìn)程休眠,如果事件發(fā)生,將發(fā)生事件的fd拷貝一份放到內(nèi)核鏈表,每個(gè)節(jié)點(diǎn)對(duì)應(yīng)一個(gè)fd,最后把鏈表的節(jié)點(diǎn)信息傳遞到用戶空間的數(shù)組中,用戶空間無需判斷事件的發(fā)生,需要判斷事件類型(讀寫等);

?

2.代碼

---pro1.c---應(yīng)用程序(epoll方式)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/epoll.h>

int main(int argc, const char *argv[])
{
    int fd1,fd2,epfd;
    char buf[128] = {0};
    struct epoll_event event;  //用于操作epoll
    struct epoll_event events[10];  //用戶空間存放發(fā)生事件的數(shù)組
    
    //創(chuàng)建epoll句柄,紅黑樹根節(jié)點(diǎn)
    epfd = epoll_create(1);
    if(epfd < 0)
    {
        printf("epoll_create fail\n");
        exit(-1);
    }
    //打開設(shè)備文件
    fd1 = open("/dev/input/mouse0", O_RDWR);
    if (fd1 < 0)
    {
        printf("鼠標(biāo)事件文件失敗\n");
        exit(-1);
    }

    fd2 = open("/dev/myled0", O_RDWR);
    if (fd2 < 0)
    {
        printf("自定義事件文件失敗\n");
        exit(-1);
    }

    //添加準(zhǔn)備就緒事件到epoll
    event.events = EPOLLIN;  //讀事件
    event.data.fd = fd1;
    if((epoll_ctl(epfd,EPOLL_CTL_ADD,fd1,&event)) < 0)
    {
        printf("epoll_ctl fd1 fail\n");
    }
    event.events = EPOLLIN;  //讀事件
    event.data.fd = fd2;
    if((epoll_ctl(epfd,EPOLL_CTL_ADD,fd2,&event)) < 0)
    {
        printf("epoll_ctl fd2 fail\n");
    }

    //監(jiān)聽時(shí)間是否發(fā)生
    while(1)
    {
        //成功接收返回時(shí)間的個(gè)數(shù),放入events數(shù)組中
        int ret = epoll_wait(epfd,events,10,-1);
        if(ret < 0)
        {
            printf("epoll_wait fail\n");
            exit(-1);   
        }
        int i;
        //循環(huán)遍歷數(shù)組,做事件的處理
        for(i=0; i<ret; i++)
        {
            if(events[i].events & EPOLLIN)  //發(fā)生事件是讀事件
            {
                read(events[i].data.fd,buf,sizeof(buf));
                printf("buf:%s\n",buf);
                memset(buf,0,sizeof(buf));
            }
        }
    }

    close(fd1);
    close(fd2);

    return 0;
}
---pro2.c---應(yīng)用程序(模擬自定義設(shè)備數(shù)據(jù)就緒)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, const char *argv[])
{
    char buf[128] = "hello world";
    int fd = open("/dev/myled0", O_RDWR);
    if (fd < 0)
    {
        printf("打開設(shè)備文件失敗\n");
        exit(-1);
    }

    write(fd, buf, sizeof(buf));

    close(fd);

    return 0;
}
---epoll.c---驅(qū)動(dòng)程序

?

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
#include<linux/poll.h>

char kbuf[128] = {0};
unsigned int major;
struct class *cls;
struct device *dev;
unsigned int condition = 0;

// 定義一個(gè)等待隊(duì)列頭
wait_queue_head_t wq_head;

// 封裝操作方法
int mycdev_open(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}

ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{
    int ret;
   
    ret = copy_to_user(ubuf, kbuf, size);
    if (ret)
    {
        printk("copy_to_ user err\n");
        return -EIO;
    }
    condition = 0; // 下一次硬件數(shù)據(jù)沒有就緒

    return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{
    int ret;
    // 從用戶拷貝數(shù)據(jù),模擬硬件數(shù)據(jù)
    ret = copy_from_user(kbuf, ubuf, size);
    if (ret)
    {
        printk("copy_from_user err\n");
        return -EIO;
    }

    condition = 1;
    wake_up_interruptible(&wq_head);

    return 0;
}
//封裝POLL方法
__poll_t mycdev_poll(struct file *file, struct poll_table_struct *wait)
{
    __poll_t mask = 0;
    //向上提交等待隊(duì)列頭
    poll_wait(file,&wq_head,wait);
    //根據(jù)事件是否發(fā)生給一個(gè)合適的返回值
    if(condition)
    {
        mask = POLLIN;
    }
    
    return mask;
}
int mycdev_close(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}

struct file_operations fops = {
    .open = mycdev_open,
    .read = mycdev_read,
    .poll = mycdev_poll,
    .write = mycdev_write,
    .release = mycdev_close,
};

// 入口函數(shù)
static int __init mycdev_init(void)
{
    //初始化等待隊(duì)列
    init_waitqueue_head(&wq_head);

    major = register_chrdev(0, "myled", &fops);
    if (major < 0)
    {
        printk("字符設(shè)備驅(qū)動(dòng)注冊(cè)失敗\n");
        return major;
    }
    printk("字符設(shè)備驅(qū)動(dòng)注冊(cè)成功:major=%d\n", major);

    // 向上提交目錄
    cls = class_create(THIS_MODULE, "MYLED");
    if (IS_ERR(cls))
    {
        printk("向上提交目錄失敗\n");
        return -PTR_ERR(cls);
    }
    printk("向上提交目錄成功\n");

    // 向上提交設(shè)備節(jié)點(diǎn)信息
    int i;
    for (i = 0; i < 3; i++)
    {
        dev = device_create(cls, NULL, MKDEV(major, i), NULL, "myled%d", i);
        if (IS_ERR(dev))
        {
            printk("向上提交設(shè)備節(jié)點(diǎn)信息失敗\n");
            return -PTR_ERR(dev);
        }
    }
    printk("向上提交設(shè)備節(jié)點(diǎn)信息成功\n");

    return 0;
}

// 出口函數(shù)
static void __exit mycdev_exit(void)
{
    // 銷毀設(shè)備節(jié)點(diǎn)信息
    int i;
    for (i = 0; i < 3; i++)
    {
        device_destroy(cls, MKDEV(major, i));
    }

    // 銷毀目錄信息
    class_destroy(cls);

    // 字符設(shè)備驅(qū)動(dòng)注銷
    unregister_chrdev(major, "myled");
}

// 聲明
// 入口函數(shù)地址
module_init(mycdev_init);
// 出口函數(shù)地址
module_exit(mycdev_exit);
// 遵循的GPL協(xié)議
MODULE_LICENSE("GPL");

?

3.測(cè)試結(jié)果

?執(zhí)行pro2.c,自定義事件被監(jiān)聽到;

?在ubuntu上動(dòng)鼠標(biāo),鼠標(biāo)事件被監(jiān)聽;

驅(qū)動(dòng)開發(fā),IO多路復(fù)用實(shí)現(xiàn)過程,epoll方式,驅(qū)動(dòng)開發(fā),驅(qū)動(dòng)開發(fā),stm32,c語言,嵌入式硬件文章來源地址http://www.zghlxwxcb.cn/news/detail-731813.html

到了這里,關(guān)于驅(qū)動(dòng)開發(fā),IO多路復(fù)用實(shí)現(xiàn)過程,epoll方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • IO多路復(fù)用之select/poll/epoll

    IO多路復(fù)用之select/poll/epoll

    掌握select編程模型,能夠?qū)崿F(xiàn)select版本的TCP服務(wù)器. 掌握poll編程模型,能夠?qū)崿F(xiàn)poll版本的TCP服務(wù)器. 掌握epoll的編程模型,能夠?qū)崿F(xiàn)epoll版本的TCP服務(wù)器. epoll的LT模式和ET模式. 理解select和epoll的優(yōu)缺點(diǎn)對(duì)比. 提示:以下是本篇文章正文內(nèi)容,下面案例可供參考 多路轉(zhuǎn)接天然的是讓我

    2023年04月09日
    瀏覽(20)
  • 【高并發(fā)網(wǎng)絡(luò)通信架構(gòu)】3.引入IO多路復(fù)用(select,poll,epoll)實(shí)現(xiàn)高并發(fā)tcp服務(wù)端

    【高并發(fā)網(wǎng)絡(luò)通信架構(gòu)】3.引入IO多路復(fù)用(select,poll,epoll)實(shí)現(xiàn)高并發(fā)tcp服務(wù)端

    目錄 一,往期文章 二,基本概念 IO多路復(fù)用 select 模型 poll 模型 epoll 模型 select,poll,epoll 三者對(duì)比 三,函數(shù)清單 1.select 方法 2.fd_set 結(jié)構(gòu)體 3.poll 方法 4.struct pollfd 結(jié)構(gòu)體 5.epoll_create 方法 6.epoll_ctl 方法 7.epoll_wait 方法 8.struct epoll_event 結(jié)構(gòu)體 四,代碼實(shí)現(xiàn) select 操作流程 s

    2024年02月14日
    瀏覽(26)
  • 網(wǎng)絡(luò)編程 IO多路復(fù)用 [epoll版] (TCP網(wǎng)絡(luò)聊天室)

    網(wǎng)絡(luò)編程 IO多路復(fù)用 [epoll版] (TCP網(wǎng)絡(luò)聊天室)

    //head.h? ? ? ? ? ? 頭文件 //TcpGrpSer.c? ? ?服務(wù)器端 //TcpGrpUsr.c? ? ?客戶端 通過IO多路復(fù)用實(shí)現(xiàn)服務(wù)器在單進(jìn)程單線程下可以與多個(gè)客戶端交互 ?API epoll函數(shù) ?head.h TcpGrpSer.c TcpGrpUsr.c ?

    2024年02月11日
    瀏覽(24)
  • 02-Linux-IO多路復(fù)用之select、poll和epoll詳解

    02-Linux-IO多路復(fù)用之select、poll和epoll詳解

    前言: 在linux系統(tǒng)中,實(shí)際上所有的 I/O 設(shè)備都被抽象為了文件這個(gè)概念,一切皆文件,磁盤、網(wǎng)絡(luò)數(shù)據(jù)、終端,甚至進(jìn)程間通信工具管道 pipe 等都被當(dāng)做文件對(duì)待。 在了解多路復(fù)用 select、poll、epoll 實(shí)現(xiàn)之前,我們先簡單回憶復(fù)習(xí)以下兩個(gè)概念: 一、什么是多路復(fù)用: 多路

    2024年02月10日
    瀏覽(25)
  • TCP服務(wù)器的演變過程:IO多路復(fù)用機(jī)制select實(shí)現(xiàn)TCP服務(wù)器

    TCP服務(wù)器的演變過程:IO多路復(fù)用機(jī)制select實(shí)現(xiàn)TCP服務(wù)器

    手把手教你從0開始編寫TCP服務(wù)器程序,體驗(yàn)開局一塊磚,大廈全靠壘。 為了避免篇幅過長使讀者感到乏味,對(duì)【TCP服務(wù)器的開發(fā)】進(jìn)行分階段實(shí)現(xiàn),一步步進(jìn)行優(yōu)化升級(jí)。 本節(jié),在上一章節(jié)的基礎(chǔ)上,將并發(fā)的實(shí)現(xiàn)改為IO多路復(fù)用機(jī)制,使用select管理每個(gè)新接入的客戶端連

    2024年02月03日
    瀏覽(17)
  • 多路IO—POll函數(shù),epoll服務(wù)器開發(fā)流程

    多路IO—POll函數(shù),epoll服務(wù)器開發(fā)流程

    \\\"在計(jì)算機(jī)網(wǎng)絡(luò)編程中,多路IO技術(shù)是非常常見的一種技術(shù)。其中,Poll函數(shù)和Epoll函數(shù)是最為常用的兩種多路IO技術(shù)。這兩種技術(shù)可以幫助服務(wù)器端處理多個(gè)客戶端的并發(fā)請(qǐng)求,提高了服務(wù)器的性能。本文將介紹Poll和Epoll函數(shù)的使用方法,并探討了在服務(wù)器開發(fā)中使用這兩種技

    2024年02月06日
    瀏覽(18)
  • 驅(qū)動(dòng)開發(fā)--多路復(fù)用-信號(hào)

    ?每個(gè)進(jìn)程都有一個(gè)描述符數(shù)組,這個(gè)數(shù)組的下標(biāo)為描述符, 描述符的分類: 文件描述符:設(shè)備文件、管道文件 socket描述符 select:位運(yùn)算實(shí)現(xiàn) 監(jiān)控的描述符數(shù)量有限(32位機(jī)1024,64位機(jī)2048) 效率差 poll:鏈表實(shí)現(xiàn),監(jiān)控的描述符數(shù)量不限 效率差 epoll:效率最高,監(jiān)控的描述

    2024年01月22日
    瀏覽(21)
  • epoll多路復(fù)用_并發(fā)服務(wù)器

    應(yīng)用程序: 驅(qū)動(dòng)程序:

    2024年02月15日
    瀏覽(20)
  • epoll() 多路復(fù)用 和 兩種工作模式

    epoll() 多路復(fù)用 和 兩種工作模式

    epoll 是 Linux 內(nèi)核中的一個(gè) 事件驅(qū)動(dòng)I/O機(jī)制 ,用于處理多個(gè)文件描述符上的事件。它是一個(gè)高效且強(qiáng)大的I/O多路復(fù)用工具,可以用于處理大量文件描述符的I/O操作。 epoll 的主要優(yōu)點(diǎn)是它只占用較少的資源,并且比傳統(tǒng)的 select 和 poll 更易于使用。 epoll 的工作原理 是通過一個(gè)

    2024年02月11日
    瀏覽(14)
  • 深入理解網(wǎng)絡(luò) I/O 多路復(fù)用:Epoll

    深入理解網(wǎng)絡(luò) I/O 多路復(fù)用:Epoll

    ?? 嗨,您好 ?? 我是 vnjohn,在互聯(lián)網(wǎng)企業(yè)擔(dān)任 Java 開發(fā),CSDN 優(yōu)質(zhì)創(chuàng)作者 ?? 推薦專欄:Spring、MySQL、Nacos、Java,后續(xù)其他專欄會(huì)持續(xù)優(yōu)化更新迭代 ??文章所在專欄:網(wǎng)絡(luò) I/O ?? 我當(dāng)前正在學(xué)習(xí)微服務(wù)領(lǐng)域、云原生領(lǐng)域、消息中間件等架構(gòu)、原理知識(shí) ?? 向我詢問任何您想

    2024年02月05日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包