国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

wordpress所有文章網(wǎng)站排名優(yōu)化推廣

wordpress所有文章,網(wǎng)站排名優(yōu)化推廣,有什么網(wǎng)站可以做畢業(yè)影像,網(wǎng)站建設(shè)的方法文章目錄 IO模型多路轉(zhuǎn)接select 和 pollepoll IO模型 在還在學(xué)習(xí)語言的階段,C里使用cin,或者是C使用scanf的時(shí)候,總是要等著我們輸入數(shù)據(jù)才執(zhí)行,這種IO是阻塞IO。下面是比較正式的說法。 阻塞IO: 在內(nèi)核將數(shù)據(jù)準(zhǔn)備好之前&#xf…

文章目錄

    • IO模型
    • 多路轉(zhuǎn)接
      • select 和 poll
      • epoll

IO模型

在還在學(xué)習(xí)語言的階段,C++里使用cin,或者是C使用scanf的時(shí)候,總是要等著我們輸入數(shù)據(jù)才執(zhí)行,這種IO是阻塞IO。下面是比較正式的說法。
阻塞IO: 在內(nèi)核將數(shù)據(jù)準(zhǔn)備好之前,系統(tǒng)調(diào)用會(huì)一直等待數(shù)據(jù)的獲取數(shù)據(jù)的做法,就是阻塞IO。

所以網(wǎng)絡(luò)套接字,在你沒有自行設(shè)置的情況下,用的也是阻塞方式IO。

上面說的仿佛只有讀取一種情況,那么寫呢?
實(shí)際上寫也是有一樣的問題,內(nèi)核有緩沖區(qū)的空間才寫,沒有緩沖區(qū)空間就一樣得阻塞。

非阻塞IO:顧名思義,如果需求的數(shù)據(jù),內(nèi)核還沒卓備好,那么操作系統(tǒng)就會(huì)直接返回。

在C語言里,如果你使用C接口的非阻塞IO,如果沒收到數(shù)據(jù)系統(tǒng)調(diào)用就返回,那么 宏變量 errno就會(huì)被設(shè)置,其值是EWOULDBLOCK 錯(cuò)誤碼。
C在C11標(biāo)準(zhǔn)之后,C++11標(biāo)準(zhǔn)之后,都是支持線程安全的。

那么問題來了,究竟什么是IO呢?
等待數(shù)據(jù) + 拷貝數(shù)據(jù)
我們發(fā)現(xiàn)不論是網(wǎng)絡(luò)的套接字,亦或者是我們常用的自己的輸入輸出,其實(shí)無非都在等待一些數(shù)據(jù),把這些數(shù)據(jù)拷貝進(jìn)我們的內(nèi)存交由程序處理。

多路轉(zhuǎn)接

理解多路轉(zhuǎn)接之前,我們先思考一個(gè)問題,
IO=等待+拷貝。

那我們?cè)撌裁磿r(shí)候區(qū)拷貝呢?
一些比較經(jīng)典的操作就是,輪詢,信號(hào)。
所謂輪詢就是,每當(dāng)我需要數(shù)據(jù),我就問問你,數(shù)據(jù)好了沒,沒有我就稍等一會(huì)再來接著問,知道數(shù)據(jù)好了我取走。
所謂信號(hào)就是,當(dāng)你數(shù)據(jù)好了你來通知我,讓我來取走數(shù)據(jù)。

我們知道,一個(gè)主機(jī)可以和其他多個(gè)主機(jī)建立TCP鏈接,也就是需要使用多個(gè)套接字。

那么每當(dāng)有一個(gè)新的連接來臨,我們不想中斷我主線程的業(yè)務(wù),但是新連接的數(shù)據(jù)收發(fā)也要管理。該如何呢? 其中一般想到的是,開多個(gè)線程。
開多線程固然是一種解決方案,其對(duì)于一般服務(wù)器負(fù)載也沒問題。

那么有成千上萬的連接來臨呢?要知道創(chuàng)建新線程也是有開銷的,根據(jù)我的Linux下的POSIX線程庫正常創(chuàng)建線程(不重新設(shè)置棧大小等),那么每一個(gè)線程約需要10MiB的空間。
算下來4GiB的內(nèi)存,用戶一般有3GiB,那么就是說約莫只有300個(gè)線程的情況,顯然算不上高并發(fā)。

因此就有一種IO模型,其處于非阻塞IO,你的每一個(gè)文件描述符(windows下叫文件句柄),都有一個(gè)中間者來給你管理,當(dāng)這些句柄有數(shù)據(jù)來臨時(shí),他來通知你,告訴你改處理這些數(shù)據(jù)了。而這就是多路轉(zhuǎn)接。

下面介紹Linux多路轉(zhuǎn)接常用的函數(shù),select,poll,和epoll

select 和 poll


int select (int __nfds, fd_set *__restrict __readfds,fd_set *__restrict __writefds,fd_set *__restrict __exceptfds,struct timeval *__restrict __timeout);void FD_CLR(int fd, fd_set *set);int  FD_ISSET(int fd, fd_set *set);void FD_SET(int fd, fd_set *set);void FD_ZERO(fd_set *set);

fd_set # 文件描述符集的類型

注:select和poll在2.6版本之后用的較少,因?yàn)楹髞淼臋C(jī)器內(nèi)存都相對(duì)較大,同時(shí)主要因?yàn)橛辛薳poll的出現(xiàn),使之取代了select。

select維護(hù)了一個(gè)文件描述符集,FDS,其類型如上面的 fd_set,你可以用一些列函數(shù)接口來操作。當(dāng)你有一個(gè)文件描述符是5號(hào)文件描述符,那么你就可以調(diào)用 FD_SET取設(shè)置入你的fd_set的數(shù)據(jù)類型里面。然后最后交給select幫你管理。

雖然答題過程如上輸代碼一言,但是其實(shí)際使用并不方便。原因也十分簡單,select的思想處理其實(shí)是一種輪詢的方式。、,這導(dǎo)致你每次都要設(shè)置文件描述符。
下面是一段示例代碼。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>#define MAX_FD 10  // 最大文件描述符數(shù)量
#define BUFFER_SIZE 1024  // 讀取緩沖區(qū)大小int main() {int fd[MAX_FD];  // 存儲(chǔ)文件描述符的數(shù)組fd_set read_fds;  // select的可讀文件描述符集合int max_fd = 0;  // 當(dāng)前最大的文件描述符char buffer[BUFFER_SIZE];  // 讀取數(shù)據(jù)的緩沖區(qū)int i, ret;// 初始化文件描述符,這里只是示例,實(shí)際情況可能是套接字for (i = 0; i < MAX_FD; i++) {fd[i] = -1;  // 初始化為-1,表示未使用}// 假設(shè)我們監(jiān)聽標(biāo)準(zhǔn)輸入(文件描述符0)fd[0] = 0;max_fd = 0;  // 標(biāo)準(zhǔn)輸入的文件描述符是0while (1) {// 清空fd集合FD_ZERO(&read_fds);// 將需要監(jiān)聽的文件描述符加入到fd集合for (i = 0; i <= max_fd; i++) {if (fd[i] != -1) {FD_SET(fd[i], &read_fds);}}// 設(shè)置超時(shí)時(shí)間,這里設(shè)置為永遠(yuǎn)等待struct timeval timeout;timeout.tv_sec = 10;  // 10秒timeout.tv_usec = 0;  // 0微秒// 調(diào)用selectret = select(max_fd + 1, &read_fds, NULL, NULL, &timeout);if (ret == -1) {perror("select error");exit(EXIT_FAILURE);} else if (ret == 0) {printf("select timeout\n");continue;}// 檢查哪個(gè)文件描述符可讀for (i = 0; i <= max_fd; i++) {if (fd[i] != -1 && FD_ISSET(fd[i], &read_fds)) {// 這里處理文件描述符i的數(shù)據(jù)memset(buffer, 0, BUFFER_SIZE);ssize_t count = read(fd[i], buffer, BUFFER_SIZE - 1);if (count > 0) {printf("Read from fd %d: %s\n", fd[i], buffer);} else if (count == 0) {// EOF,可能需要關(guān)閉文件描述符close(fd[i]);fd[i] = -1;} else {// 讀取錯(cuò)誤perror("read error");}}}}return 0;
}

你會(huì)發(fā)現(xiàn)意見很讓人覺得效率低且麻煩的事情,那就是select每一次都需要遍歷。如同輪詢一般,因?yàn)槟惴胚M(jìn)去的select文件描述符發(fā)生事件時(shí),select并不會(huì)告訴你具體是誰發(fā)生了,只知道在 FD_MAX(目前最大的文件描述符為止),有事件發(fā)生,這就顯得麻煩且效率低下。不過因?yàn)閟elect上限文件描述符大多數(shù)都是1024,也就是 FD_SETSIZE 宏。所以select的整體效率不算高,但是其適用于一些比較沒有那么支持性能的機(jī)器。
總結(jié):
1.每次調(diào)用select都需要把fd集合從用戶態(tài)往內(nèi)核態(tài)拷貝一次,而每次拷貝都需要通過系統(tǒng)調(diào)用進(jìn)入內(nèi)核態(tài),且在內(nèi)核也是遍歷訪問這個(gè)開銷在fd很多時(shí)會(huì)很大
2.select支持的文件描述符數(shù)量太小了,默認(rèn)是1024
3.select返回后,需要遍歷文件描述符集合,來獲取已經(jīng)就緒的socket
4.select不支持O_NONBLOCK
5.每次對(duì)要用第三方數(shù)組,動(dòng)不動(dòng)就需要遍歷,十分耗時(shí)

poll類似select,解決了文件描述符上限,同時(shí)解決了輸入輸出每次重置的問題。(也就是select每次都要傳一個(gè)表進(jìn)去,同時(shí)也要傳出來。)
具體用法不多敘述,可以自行百度。

epoll

epoll整體設(shè)計(jì)理念相較于select就比較人性化,我們知道每當(dāng)有數(shù)據(jù)來臨的時(shí)候,目前許多OS采用的都是硬件中斷,讓CPU臨時(shí)去被數(shù)據(jù)接受之后存儲(chǔ)起來。比如你的鍵盤輸入就是如此。
那么為什么不把每個(gè)文件描述符有數(shù)據(jù)需要處理時(shí),都會(huì)有信號(hào),那么既然如此我維護(hù)這份記錄就行,因此epoll就是如此做的。每當(dāng)一個(gè)進(jìn)程調(diào)用epoll時(shí),會(huì)創(chuàng)建一個(gè)紅黑樹,將你關(guān)心的文件描述符添加進(jìn)去,每當(dāng)有事件來臨,他就去紅黑樹里面找關(guān)心了這個(gè)事件與否,然后如果發(fā)現(xiàn)時(shí)關(guān)心了的,那么就通過回調(diào)(ep_poll_callback )把這個(gè)節(jié)點(diǎn)給放到 另外的就緒隊(duì)列上去,如此你就知道這個(gè)事件需要用了。

因此總結(jié)一下:使得epoll關(guān)心文件描述符的方法
調(diào)用epoll_create創(chuàng)建一個(gè)epoll句柄;
調(diào)用epoll_ctl, 將要監(jiān)控的文件描述符進(jìn)行注冊(cè);
調(diào)用epoll_wait, 等待文件描述符就緒;

具體調(diào)用可查詢手冊(cè),下面是例子

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>#define MAX_EVENTS 10
#define PORT 8080int main() {int listen_sock, conn_sock, epfd;struct sockaddr_in serv_addr;struct epoll_event event;struct epoll_event events[MAX_EVENTS];int num_fds;// 創(chuàng)建監(jiān)聽socketlisten_sock = socket(AF_INET, SOCK_STREAM, 0);if (listen_sock == -1) {perror("socket");exit(EXIT_FAILURE);}memset(&serv_addr, 0, sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);serv_addr.sin_port = htons(PORT);// 綁定socketif (bind(listen_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) {perror("bind");exit(EXIT_FAILURE);}// 監(jiān)聽socketif (listen(listen_sock, 5) == -1) {perror("listen");exit(EXIT_FAILURE);}// 創(chuàng)建epoll實(shí)例epfd = epoll_create1(0);if (epfd == -1) {perror("epoll_create");exit(EXIT_FAILURE);}// 添加監(jiān)聽socket到epoll實(shí)例event.data.fd = listen_sock;event.events = EPOLLIN;if (epoll_ctl(epfd, EPOLL_CTL_ADD, listen_sock, &event) == -1) {perror("epoll_ctl: listen_sock");exit(EXIT_FAILURE);}// 事件循環(huán)while (1) {num_fds = epoll_wait(epfd, events, MAX_EVENTS, -1);if (num_fds == -1) {perror("epoll_wait");exit(EXIT_FAILURE);}for (int i = 0; i < num_fds; i++) {if (events[i].data.fd == listen_sock) {// 處理新的連接conn_sock = accept(listen_sock, NULL, NULL);if (conn_sock == -1) {perror("accept");exit(EXIT_FAILURE);}printf("Accepted connection on fd %d\n", conn_sock);// 將新的連接添加到epoll實(shí)例event.data.fd = conn_sock;event.events = EPOLLIN | EPOLLET; // 邊緣觸發(fā)模式if (epoll_ctl(epfd, EPOLL_CTL_ADD, conn_sock, &event) == -1) {perror("epoll_ctl: conn_sock");exit(EXIT_FAILURE);}} else {// 處理已連接socket的數(shù)據(jù)if (events[i].events & EPOLLIN) {char buffer[1024];ssize_t count;count = read(events[i].data.fd, buffer, sizeof(buffer));if (count == -1) {perror("read");close(events[i].data.fd);} else if (count == 0) {// 連接關(guān)閉printf("Closed connection on fd %d\n", events[i].data.fd);close(events[i].data.fd);} else {// 處理讀取到的數(shù)據(jù)printf("Read %zd bytes from fd %d\n", count, events[i].data.fd);// 這里可以將數(shù)據(jù)發(fā)送回去或者進(jìn)行其他處理}}}}}close(listen_sock);return 0;
}
http://m.aloenet.com.cn/news/37786.html

相關(guān)文章:

  • 上海整站優(yōu)化公司網(wǎng)絡(luò)營銷理論
  • 網(wǎng)站建設(shè)與文字的工作成都百度推廣代理公司
  • 傳奇三端互通新開服網(wǎng)站上海推廣服務(wù)
  • 西安網(wǎng)站seo優(yōu)化網(wǎng)站運(yùn)營指標(biāo)
  • wordpress添加文章分類二級(jí)小紅書搜索優(yōu)化
  • 直播網(wǎng)站模板網(wǎng)站優(yōu)化推廣外包
  • 金品誠企網(wǎng)站建設(shè)b站2023年免費(fèi)入口
  • 樂清網(wǎng)站關(guān)鍵詞下載
  • 不用ftp做網(wǎng)站seo工作室
  • 建網(wǎng)站的公司不肯簽合同福州seo推廣優(yōu)化
  • 微網(wǎng)站制作軟件線上線下整合營銷方案
  • 推廣業(yè)務(wù)網(wǎng)站建設(shè)網(wǎng)站服務(wù)器速度對(duì)seo有什么影響
  • 青島網(wǎng)站模板建站做推廣的都是怎么推
  • 穹拓做網(wǎng)站站長工具seo查詢
  • 網(wǎng)站建設(shè)成本價(jià)瀏覽器看b站
  • 合肥知名網(wǎng)站制作新聞?lì)^條最新消息今天
  • 桂林網(wǎng)站建設(shè)凡森網(wǎng)絡(luò)網(wǎng)絡(luò)推廣用什么軟件好
  • wordpress 主題 修改鄭州seo哪家好
  • 寧波網(wǎng)絡(luò)推廣制作seo是哪里
  • 沈陽網(wǎng)站seo排名優(yōu)化愛網(wǎng)站關(guān)鍵詞查詢工具
  • 網(wǎng)站模版建站免費(fèi)引流人脈推廣軟件
  • 網(wǎng)站被降權(quán)的原因怎么知道網(wǎng)站有沒有被收錄
  • 做網(wǎng)站業(yè)務(wù)員怎么樣烘焙甜點(diǎn)培訓(xùn)學(xué)校
  • 電商視覺設(shè)計(jì)網(wǎng)站批量優(yōu)化網(wǎng)站軟件
  • 外國做營銷方案的網(wǎng)站360建站和凡科哪個(gè)好
  • 建設(shè)銀行北京東四支行網(wǎng)站愛站網(wǎng)關(guān)鍵詞排名
  • 網(wǎng)站建設(shè)下什么科目武漢seo搜索引擎優(yōu)化
  • 慈溪做無痛同濟(jì) 網(wǎng)站北京最新疫情情況
  • 寧夏網(wǎng)站設(shè)計(jì)聯(lián)系電話推廣公司屬于什么公司
  • 合肥做網(wǎng)站多少錢資源網(wǎng)