當前位置:首頁 » 編程語言 » c語言非阻塞編程
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

c語言非阻塞編程

發布時間: 2022-10-09 14:00:09

c語言 阻塞,非阻塞和多線程有什麼關系

  • 阻塞是在傳統的網路編程中我們依賴於ServerSocket,Socket進行通信,大致的框架就是ServerSocket調用accept方法,等待客戶端的連接,如果連接進來的時候則創建一個伺服器端socket,客戶端和伺服器端socket建立好InputStream 和outputStream通道進行通信,在這個網路IO的過程中inputStream的read 和outputStream的write方法都可能發送阻塞。為了減少這種阻塞對其他連接的影響,一般都會在伺服器端為每個連接開辟一個新的線程,或者使用線程池技術來避免線程的創建銷毀同時又一定程度支持並發量。然而這種情況下,如果發生大量的read 或者write阻塞線程池的效率會大大降低,而且操作系統也額外需要頻繁的處理cpu的切換。

  • 非阻塞式通信實際是對上述模式的擴展,它的核心思想是為傳統的socket加入事件監聽的功能,操作系統可以在socket和serversocket上進行事件監聽,一旦監聽的對象發生了連接和可讀可寫的事件,監聽器就會對注冊了事件的對象返回相應的通知。在javaNIO中實現這一套的機制就是把socket 和ServerSocket重寫成為SocketChanel,ServerSocketChanel,他們的底層仍然使用socket實現,所以原則上javaNIO包可以完全實現阻塞和非阻塞兩種編程模式。事件監聽的功能由Selection類完成,他使用select方法一直阻塞式監聽注冊了的事件是否發生,對於每一個發生的事件,他都會返回一個selectionKey,通過這個key我們就可以確定這個事件的發生源(socket)和相關信息。對於ServerSocketChanel,Socketchanel分別對應了不同的事件,serverChanel只有OP_ACCEPT代表是否可以接受連接,而socketChanel則有OP_CONNECT、read、write事件。筆者認為與阻塞IO相比他的優勢在於可以避免read 和write的阻塞,因為這個比較具有實際意義的。比如是一個網路文件傳輸系統,read方法可能會因為網路原因發生多次阻塞,使用非阻塞IO read的話線程可以立即返回去處理其他任務。

  • 多線程是在進程中進一步去劃分的獨立單元。

Ⅱ c語言的recv()非阻塞方法怎麼弄哦

需要將recv設置超時,Linux下設置超時如下:

//設置發送超時
struct timeval timeout={3,0};//3s
setsockopt(socket,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(struct timeval));
//設置接收超時
setsockopt(socket,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval));
windows下設置超時如下:

int timeout = 3000; //3s
int ret=setsockopt(sock_fd,SOL_SOCKET,SO_SNDTIMEO,&timeout,sizeof(timeout));
int ret=setsockopt(sock_fd,SOL_SOCKET,SO_RCVTIMEO,&timeout,sizeof(timeout));

Ⅲ C語言阻塞、非阻塞和多線程有什麼關系

這個問題我知道!說到阻塞和非阻塞的概念,就要了解同步和非同步的概念吧同步:多個線程可以同時訪問同一個資源。比如對一個變數而言,線程們可以同時對他進行讀寫。使用場景:多個線程同時訪問一塊數據,也叫共享區。對於多個線程同時訪問一塊數據的時候,必須使用同步,否則可能會出現不安全的情況。比如資料庫中的臟讀。但是,多個線程同時訪問一塊數據,有一種情況不需要同步技術,那就是原子操作,也就是說操作系統在底層保證了操作要麼全部做完,要麼不做。非同步:使用場景:只有一個線程訪問當前的數據。比如,觀察者模式,沒有共享區,主題發生變化,通知觀察者更新,主題繼續做自己的事情,不需要等待觀察者更新完成後再工作。同步分為阻塞IO和非同步IO非同步可以分為阻塞IO和非阻塞的IO非同步阻塞IO通過select和epoll實現

Ⅳ C語言Socket通信 非阻塞問題 誰能幫我解釋解釋這段代碼呀

非堵塞通信,可以使用MFC的CAsyncSocket類。

Ⅳ windows下C語言非阻塞方式讀取鍵盤緩沖區

有所不同。伺服器是網路的節點,存儲、處理網路上80%的數據、信息,在網路中起到舉足輕重的作用。它們是為客戶端計算機提供各種服務的高性能的計算機,其高性能主要表高速度的運算能力、長時間的可靠運行、強大的外部數據吞吐能力等方面。伺服器的構成與普通電腦類似,

Ⅵ c語言中select函數的作用

在編程的過程中,經常會遇到許多阻塞的函數,好像read和網路編程時使用的recv, recvfrom函數都是阻塞的函數,當函數不能成功執行的時候,程序就會一直阻塞在這里,無法執行下面的代碼。這是就需要用到非阻塞的編程方式,使用selcet函數就可以實現非阻塞編程。
selcet函數是一個輪循函數,即當循環詢問文件節點,可設置超時時間,超時時間到了就跳過代碼繼續往下執行。

Select的函數格式:

int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval*timeout);

select函數有5個參數
第一個是所有文件節點的最大值加1,如果我有三個文件節點1、4、6,那第一個參數就為7(6+1)

第二個是可讀文件節點集,類型為fd_set。通過FD_ZERO(&readfd);初始化節點集;然後通過FD_SET(fd, &readfd);把需要監聽是否可讀的節點加入節點集
第三個是可寫文件節點集中,類型為fd_set。操作方法和第二個參數一樣。
第四個參數是檢查節點錯誤集。
第五個參數是超時參數,類型為struct timeval,然後可以設置超時時間,分別可設置秒timeout.tv_sec和微秒timeout.tv_usec。
然後調用select函數,用FD_ISSET()函數判斷節點是否可讀寫。返回值不為0表示可讀寫,為0表示不可讀寫。select函數的返回值為是一個整數,表示有幾個節點可讀寫。

先說明兩個結構體:
第一,struct fd_set可以理解為一個集合,這個集合中存放的是文件描述符(filedescriptor),即文件句柄,這可以是我們所說的普通意義的文件,當然Unix下任何設備、管道、FIFO等都是文件形式,全部包括在內,所以毫無疑問一個socket就是一個文件,socket句柄就是一個文件描述符。fd_set集合可以通過一些宏由人為來操作,比如清空集合FD_ZERO(fd_set *),將一個給定的文件描述符加入集合之中FD_SET(int ,fd_set*),將一個給定的文件描述符從集合中刪除FD_CLR(int,fd_set*),檢查集合中指定的文件描述符是否可以讀寫FD_ISSET(int ,fd_set* )。

第二,struct timeval是一個大家常用的結構,用來代表時間值,有兩個成員,一個是秒數,另一個是毫秒數。

具體解釋select的參數:
int maxfdp是一個整數值,是指集合中所有文件描述符的范圍,即所有文件描述符的最大值加1,不能錯!在Windows中這個參數的值無所謂,可以設置不正確。

fd_set * readfds是指向fd_set結構的指針,這個集合中應該包括文件描述符,我們是要監視這些文件描述符的讀變化的,即我們關心是否可以從這些文件中讀取數據了,如果這個集合中有一個文件可讀,select就會返回一個大於0的值,表示有文件可讀,如果沒有可讀的文件,則根據timeout參數再判斷是否超時,若超出timeout的時間,select返回0,若發生錯誤返回負值。可以傳入NULL值,表示不關心任何文件的讀變化。

fd_set * writefds是指向fd_set結構的指針,這個集合中應該包括文件描述符,我們是要監視這些文件描述符的寫變化的,即我們關心是否可以向這些文件中寫入數據了,如果這個集合中有一個文件可寫,select就會返回一個大於0的值,表示有文件可寫,如果沒有可寫的文件,則根據timeout參數再判斷是否超時,若超出timeout的時間,select返回0,若發生錯誤返回負值。可以傳入NULL值,表示不關心任何文件的寫變化。

fd_set * errorfds同上面兩個參數的意圖,用來監視文件錯誤異常。
struct timeval * timeout是select的超時時間,這個參數至關重要,它可以使select處於三種狀態,第一,若將NULL以形參傳入,即不傳入時間結構,就是將select置於阻塞狀態,一定等到監視文件描述符集合中某個文件描述符發生變化為止;第二,若將時間值設為0秒0毫秒,就變成一個純粹的非阻塞函數,不管文件描述符是否有變化,都立刻返回繼續執行,文件無變化返回0,有變化返回一個正值;第三,timeout的值大於0,這就是等待的超時時間,即select在timeout時間內阻塞,超時時間之內有事件到來就返回了,否則在超時後不管怎樣一定返回,返回值同上述。

返回值:返回狀態發生變化的描述符總數。
負值:select錯誤
正值:某些文件可讀寫或出錯
0:等待超時,沒有可讀寫或錯誤的文件

Ⅶ c語言中非阻塞單線程輸入循環怎麼做

繼承Thread類,須重寫父類的run()方法,另一種:實現Runnable介面,也是實現run()方法。run() 方法很重要,是當你新建一個線程,運行時的核心,注意,你不要自己去調用run()方法,如果你自己調用,就只是你寫那行調用代碼,運行那行代碼的線程在執行該方法,而不是你新建線程執行的。這一點,也是我之前多線程編程常混亂的。
說到這,如何新建一個線程呢?很簡單: Thread newThread = new Thread( 參數) ; 構造方法中的參數,為前面兩種之前的實現類的一個實例。那麼當你調用了: newThread.start()方法後,就新啟動了一個線程,那麼當該線程執行了run(),即參數中實例的run()方法,就是該線程執行的主體。
注意: 一個線程執行的主體run()方法,是不需要你顯示調用的。

Ⅷ C語言如何在子線程中等待輸入的同時(scanf或者getchar等等之類的輸入),不阻塞其他線程去進行輸出

要用_kbhit()函數, 非阻塞

//direct代表方向:0-向右,1-向下,2-向左,3-向上
while(1)
{
if(_kbhit())//如果按下的是方向鍵或功能鍵,_getch()要調用兩次,第一次返回0XE0或0
{
c=_getch();//上:72下:80左:75右:77
if(c==0XE0||c==0) c=_getch();
if(c==72&&(direct!=1||direct!=3))
{
direct=3;
}
elseif(c==80&&(direct!=1||direct!=3))
{
direct=1;
}
elseif(c==75&&(direct!=0||direct!=2))
{
direct=2;
}
elseif(c==77&&(direct!=0||direct!=2))
{
direct=0;
}
}
}

Ⅸ udp非阻塞怎麼寫 linuxc語言

int flag=fcntl(fd,F_GETFL,0); flag |= O_NONBLOCK; if(fcntl(fd,F_SETFL,flag) < 0){ perror("fcntl"); exit(1); }

Ⅹ C語言如何讓程序一直不斷運行直到按了某個鍵以後停止,代碼怎麼寫

可以參考下面的代碼:

#include <stdio.h>

#include <conio.h>

#include <windows.h>

main( )

{

int p;

while( ! _kbhit() ) {

// run progs

_cputs( "Please hit me ! " );

Sleep(500);

}

return 0;

}

(10)c語言非阻塞編程擴展閱讀:

kbhit()是一個C和C++函數,用於非阻塞地響應鍵盤輸入事件。

函數名:kbhit()

功能及返回值: 檢查當前是否有鍵盤輸入,若有則返回一個非0值,否則返回0。

用 法:int kbhit(void);

C++語言包含頭文件: include <conio.h>。

C語言不需包含額外頭文件。

在VC++6.0下為_kbhit()

功能及返回值同上。