使用 libevent 構建高性能網絡應用

使用 libevent 構建高性能網絡應用

在現代網絡編程中,高性能和可擴展性是開發者追求的核心目標。為了實現這一目標,許多開發者選擇使用事件驅動庫來管理 I/O 操作和事件處理。libevent 是一個輕量級、高性能的事件通知庫,廣泛應用于網絡服務器、代理、緩存等場景。

本文將詳細介紹 libevent 的核心概念、使用方法以及如何利用它構建高性能的網絡應用。


1. 什么是 libevent?

libevent 是一個用 C 語言編寫的事件驅動庫,旨在提供一種高效的方式來處理 I/O 事件、定時器和信號。它的主要特點包括:

  • 跨平臺:支持 Linux、macOS、Windows 等多種操作系統。
  • 高性能:基于操作系統提供的高效 I/O 多路復用機制(如 epollkqueueIOCP 等)。
  • 易用性:提供了簡潔的 API,方便開發者快速上手。
  • 可擴展性:支持多種事件類型(如 I/O 事件、定時器事件、信號事件)。

libevent 被廣泛應用于許多知名項目,如 Memcached、Tor 和 Chromium。


2. 安裝 libevent

在開始使用 libevent 之前,需要先安裝它。

在 Ubuntu 上安裝

sudo apt-get install libevent-dev

在 macOS 上安裝

brew install libevent

在 Windows 上安裝

可以通過 vcpkg 安裝:

vcpkg install libevent

3. 核心概念

事件循環(Event Loop)

libevent 的核心是事件循環(Event Loop),它負責監聽和分發事件。事件循環會不斷地檢查是否有事件發生,并調用相應的回調函數進行處理。

事件(Event)

事件是 libevent 的基本單位,表示一個需要監聽的操作。事件可以是以下幾種類型:

  • I/O 事件:如文件描述符可讀或可寫。
  • 定時器事件:在指定時間后觸發。
  • 信號事件:當進程接收到特定信號時觸發。

事件基(Event Base)

事件基是事件循環的核心結構,用于管理所有的事件。每個事件都需要與一個事件基關聯。


4. 基本用法

初始化事件基

在使用 libevent 之前,需要先初始化一個事件基:

#include <event2/event.h>struct event_base *base = event_base_new();
if (!base) {fprintf(stderr, "Could not initialize libevent!\n");return 1;
}

創建事件

創建一個事件需要指定事件類型、文件描述符、回調函數以及回調函數的參數。例如,創建一個監聽標準輸入可讀事件的事件:

#include <event2/event.h>
#include <stdio.h>void stdin_read_cb(evutil_socket_t fd, short events, void *arg) {char buf[1024];int len = read(fd, buf, sizeof(buf) - 1);if (len > 0) {buf[len] = '\0';printf("Read: %s\n", buf);} else {printf("EOF or error\n");event_base_loopexit((struct event_base *)arg, NULL);}
}int main() {struct event_base *base = event_base_new();if (!base) {fprintf(stderr, "Could not initialize libevent!\n");return 1;}struct event *ev = event_new(base, STDIN_FILENO, EV_READ | EV_PERSIST, stdin_read_cb, base);if (!ev) {fprintf(stderr, "Could not create event!\n");return 1;}event_add(ev, NULL);event_base_dispatch(base);event_free(ev);event_base_free(base);return 0;
}

運行事件循環

調用 event_base_dispatch 啟動事件循環:

event_base_dispatch(base);

事件循環會一直運行,直到沒有更多事件需要處理或調用 event_base_loopexit 退出。


5. 高級特性

定時器事件

libevent 支持創建定時器事件,在指定時間后觸發回調函數。例如,創建一個 2 秒后觸發的定時器:

#include <event2/event.h>
#include <stdio.h>void timer_cb(evutil_socket_t fd, short events, void *arg) {printf("Timer triggered!\n");
}int main() {struct event_base *base = event_base_new();if (!base) {fprintf(stderr, "Could not initialize libevent!\n");return 1;}struct event *ev = evtimer_new(base, timer_cb, NULL);if (!ev) {fprintf(stderr, "Could not create timer event!\n");return 1;}struct timeval tv = {2, 0};evtimer_add(ev, &tv);event_base_dispatch(base);event_free(ev);event_base_free(base);return 0;
}

信號事件

libevent 還支持監聽信號事件。例如,監聽 SIGINT 信號(Ctrl+C):

#include <event2/event.h>
#include <stdio.h>
#include <signal.h>void signal_cb(evutil_socket_t fd, short events, void *arg) {printf("Caught signal %d!\n", fd);event_base_loopexit((struct event_base *)arg, NULL);
}int main() {struct event_base *base = event_base_new();if (!base) {fprintf(stderr, "Could not initialize libevent!\n");return 1;}struct event *ev = evsignal_new(base, SIGINT, signal_cb, base);if (!ev) {fprintf(stderr, "Could not create signal event!\n");return 1;}event_add(ev, NULL);event_base_dispatch(base);event_free(ev);event_base_free(base);return 0;
}

6. 實際應用場景

高性能網絡服務器

libevent 可以用于構建高性能的網絡服務器。例如,使用 libevent 實現一個簡單的 TCP 回顯服務器:

#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>void echo_read_cb(struct bufferevent *bev, void *ctx) {struct evbuffer *input = bufferevent_get_input(bev);struct evbuffer *output = bufferevent_get_output(bev);evbuffer_add_buffer(output, input);
}void echo_event_cb(struct bufferevent *bev, short events, void *ctx) {if (events & BEV_EVENT_ERROR) {perror("Error from bufferevent");}if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) {bufferevent_free(bev);}
}void accept_conn_cb(struct evconnlistener *listener, evutil_socket_t fd,struct sockaddr *address, int socklen, void *ctx) {struct event_base *base = evconnlistener_get_base(listener);struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);bufferevent_setcb(bev, echo_read_cb, NULL, echo_event_cb, NULL);bufferevent_enable(bev, EV_READ | EV_WRITE);
}int main() {struct event_base *base = event_base_new();if (!base) {fprintf(stderr, "Could not initialize libevent!\n");return 1;}struct sockaddr_in sin;memset(&sin, 0, sizeof(sin));sin.sin_family = AF_INET;sin.sin_port = htons(8080);struct evconnlistener *listener = evconnlistener_new_bind(base, accept_conn_cb, NULL, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1,(struct sockaddr *)&sin, sizeof(sin));if (!listener) {fprintf(stderr, "Could not create listener!\n");return 1;}event_base_dispatch(base);evconnlistener_free(listener);event_base_free(base);return 0;
}

7. 總結

libevent 是一個功能強大且易于使用的事件驅動庫,適用于構建高性能的網絡應用。通過它,開發者可以輕松管理 I/O 事件、定時器和信號,而無需關心底層平臺的差異。

希望本文能幫助你快速上手 libevent,并將其應用到實際項目中。如果你有任何問題或建議,歡迎在評論區留言!


參考文檔

  • libevent 官方網站
  • libevent GitHub 倉庫
  • libevent 官方文檔

Happy coding! 🚀

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/73050.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/73050.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/73050.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HeyGem.ai 全離線數字人生成引擎加入 GitCode:開啟本地化 AIGC 創作新時代

在人工智能技術飛速演進的時代&#xff0c;數據隱私與創作自由正成為全球開發者關注的焦點。硅基智能旗下開源項目 HeyGem.ai 近日正式加入 GitCode&#xff0c;以全球首個全離線數字人生成引擎的顛覆性技術&#xff0c;重新定義人工智能生成內容&#xff08;AIGC&#xff09;的…

【leetcode hot 100 39】組合總和

錯誤解法一&#xff1a;每一次回溯都遍歷提供的數組 class Solution {public List<List<Integer>> combinationSum(int[] candidates, int target) {List<List<Integer>> result new ArrayList<List<Integer>>();List<Integer> te…

VSCODE右下角切換環境沒用

VSCODE惦記右下角python版本&#xff0c;切換別的虛擬環境時&#xff0c;始終切換不了&#xff0c;同時右下角彈出&#xff1a; Client Pylance: connection to server is erroring. 取消繼承環境也改了。https://www.cnblogs.com/coreylin/p/17509610.html 還是不行&#xf…

【sql靶場】第23、25,25a關過濾繞過保姆級教程

目錄 【sql靶場】第23、25-28關過濾繞過保姆級教程 第二十三關 第二十五關 1.爆出數據庫 2.爆出表名 3.爆出字段 4.爆出賬號密碼 【sql靶場】第23、25&#xff0c;25a關過濾繞過保姆級教程 第二十三關 從本關開始又是get傳參&#xff0c;并且還有了對某些字符或字段的過…

python每日十題(5)

保留字&#xff0c;也稱關鍵字&#xff0c;是指被編程語言內部定義并保留使用的標識符。Python 3.x版本中有35個保留字&#xff0c;分別為&#xff1a;and, as,assert,async,await,break,class,continue,def,del,elif,else, except, False, finally,for,from,global, if,import…

Pytorch使用手冊—自定義 C++ 和 CUDA 擴展(專題五十二)

提示 從 PyTorch 2.4 開始,本教程已被廢棄。請參考 PyTorch 自定義操作符,了解關于通過自定義 C++/CUDA 擴展擴展 PyTorch 的最新指南。 PyTorch 提供了大量與神經網絡、任意張量代數、數據處理等相關的操作。然而,您可能仍然會發現自己需要一個更自定義的操作。例如,您可能…

CHM(ConcurrentHashMap)中的 sizeCtl 的作用與值變化詳解

學海無涯&#xff0c;志當存遠。燃心礪志&#xff0c;奮進不輟。愿諸君得此雞湯&#xff0c;如沐春風&#xff0c;學業有成。若覺此言甚善&#xff0c;煩請賜贊一枚&#xff0c;共勵學途&#xff0c;同鑄輝煌 ConcurrentHashMap常簡寫為CHM&#xff0c;尤其是在討論并發編程時。…

VLAN綜合實驗報告

一、實驗拓撲 網絡拓撲結構包括三臺交換機&#xff08;LSW1、LSW2、LSW3&#xff09;、一臺路由器&#xff08;AR1&#xff09;以及六臺PC&#xff08;PC1-PC6&#xff09;。交換機之間通過Trunk鏈路相連&#xff0c;交換機與PC、路由器通過Access或Hybrid鏈路連接。 二、實驗…

OpenGL ES ->計算多個幀緩沖對象(Frame Buffer Object)+疊加多個濾鏡作用后的Bitmap

XML文件 <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"><…

Java線程池深度解析:從使用到調優

適合人群&#xff1a;Java中級開發者 | 并發編程入門者 | 系統調優實踐者 目錄 一、引言&#xff1a;為什么線程池是Java并發的核心&#xff1f; 二、線程池核心知識點詳解 1. 線程池核心參數與原理 2. 線程池的創建與使用 (1) 基礎用法示例 (2) 內置線程池的隱患 3. 線…

【工具變量】全國地級市地方ZF債務數據集(2014-2023年)

地方ZF債務是地方財政運作的重要組成部分&#xff0c;主要用于基礎設施建設、公共服務及經濟發展&#xff0c;是衡量地方財政健康狀況的重要指標。近年來&#xff0c;我國地級市的地方ZF債務規模不斷變化&#xff0c;涉及一般債務和專項債務等多個方面&#xff0c;對金融市場、…

大模型訓練的調參與算力調度技術分析

大模型訓練的調參與算力調度 雖然從網絡上&#xff0c;還有通過和大模型交流&#xff0c;了解了很多訓練和微調的技術。但沒有實踐&#xff0c;也沒有什么機會實踐。因為大模型訓練門檻還是挺高的&#xff0c;想要有一手資料比較困難。如果需要多機多卡&#xff0c;硬件成本小…

深入理解 lt; 和 gt;:HTML 實體轉義的核心指南!!!

&#x1f6e1;? 深入理解 < 和 >&#xff1a;HTML 實體轉義的核心指南 &#x1f6e1;? 在編程和文檔編寫中&#xff0c;< 和 > 符號無處不在&#xff0c;但它們也是引發語法錯誤、安全漏洞和渲染混亂的頭號元兇&#xff01;&#x1f525; 本文將聚焦 <&#…

GRS認證的注意事項!GRS認證的定義

GRS認證的注意事項&#xff0c;對于企業而言&#xff0c;是通往可持續發展和環保生產道路上的重要里程碑。在追求這一認證的過程中&#xff0c;企業必須細致入微&#xff0c;確保每一個環節都符合嚴格的標準與要求。 首先&#xff0c;企業必須全面理解GRS認證的核心原則&#…

位運算--求二進制中1的個數

位運算–求二進制中1的個數 給定一個長度為 n 的數列&#xff0c;請你求出數列中每個數的二進制表示中 1 的個數。 輸入格式 第一行包含整數 n。 第二行包含 n 個整數&#xff0c;表示整個數列。 輸出格式 共一行&#xff0c;包含 n 個整數&#xff0c;其中的第 i 個數表…

Linux常用指令(3)

大家好,今天我們繼續來介紹一下linux常用指令的語法,加深對linux操作系統的了解,話不多說,來看. 1.rmdir指令 功能&#xff1a;刪除空目錄 基本語法&#xff1a; rmdir 要刪除的空目錄 ??rmdir刪除的是空目錄,如果目錄下有內容是無法刪除 2.mkdir指令 功能&#xff1a;創…

《Linux 網絡架構:基于 TCP 協議的多人聊天系統搭建詳解》

一、系統概述 本系統是一個基于 TCP 協議的多人聊天系統&#xff0c;由一個服務器和多個客戶端組成。客戶端可以連接到服務器&#xff0c;向服務器發送消息&#xff0c;服務器接收到消息后將其轉發給其他客戶端&#xff0c;實現多人之間的實時聊天。系統使用 C 語言編寫&#x…

JavaIO流的使用和修飾器模式(直擊心靈版)

系列文章目錄 JavaIO流的使用和修飾器模式 文章目錄 系列文章目錄前言一、字節流&#xff1a; 1.FileInputStream(讀取文件)2.FileOutputStream(寫入文件) 二、字符流&#xff1a; 1..基礎字符流:2.處理流&#xff1a;3.對象處理流&#xff1a;4.轉換流&#xff1a; 三、修飾器…

【設計模式】SOLID 設計原則概述

SOLID 是面向對象設計中的五大原則&#xff0c;不管什么面向對象的語言&#xff0c; 這個準則都很重要&#xff0c;如果你沒聽說過&#xff0c;趕緊先學一下。它可以提高代碼的可維護性、可擴展性和可讀性&#xff0c;使代碼更加健壯、易于測試和擴展。SOLID 代表以下五個設計原…

可發1區的超級創新思路:基于注意力機制的DSD-CNN時間序列預測模型(功率預測、交通流量預測、故障檢測)

首先聲明,該模型為原創!原創!原創! 一、應用場景 該模型主要用于時間序列數據預測問題,包含功率預測、電池壽命預測、電機故障檢測等等 二、模型整體介紹(本文以光伏功率預測為例) DSD-CNN(Depthwise-Spacewise Separable CNN)結合通道注意力機制,通過以下創新提升…