1、同一個程序在windows下可以正常查詢資料庫,在linux伺服器上無法查詢,執行select都卡住幾個小時。
你是通過網路查詢?還是分別在本機和伺服器上查詢?
最好優化下查詢語句。
或者找到對應的查詢語句發出來看看。
2、Linux內核中select,poll和epoll的區別
select:
下面是select的函數介面:
int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
select 函數監視的文件描述符分3類,分別是writefds、readfds、和exceptfds。調用後select函數會阻塞,直到有描述副就緒(有數據 可讀、可寫、或者有except),或者超時(timeout指定等待時間,如果立即返回設為null即可),函數返回。當select函數返回後,可以 通過遍歷fdset,來找到就緒的描述符。
select目前幾乎在所有的平台上支持,其良好跨平台支持也是它的一個優點。select的一 個缺點在於單個進程能夠監視的文件描述符的數量存在最大限制,在Linux上一般為1024,可以通過修改宏定義甚至重新編譯內核的方式提升這一限制,但 是這樣也會造成效率的降低。
poll:
int poll (struct pollfd *fds, unsigned int nfds, int timeout);
不同與select使用三個點陣圖來表示三個fdset的方式,poll使用一個 pollfd的指針實現。
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events to watch */
short revents; /* returned events witnessed */
};
pollfd結構包含了要監視的event和發生的event,不再使用select「參數-值」傳遞的方式。同時,pollfd並沒有最大數量限制(但是數量過大後性能也是會下降)。 和select函數一樣,poll返回後,需要輪詢pollfd來獲取就緒的描述符。
從上面看,select和poll都需要在返回後,通過遍歷文件描述符來獲取已經就緒的socket。事實上,同時連接的大量客戶端在一時刻可能只有很少的處於就緒狀態,因此隨著監視的描述符數量的增長,其效率也會線性下降。
epoll:
epoll的介面如下:
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
typedef union epoll_data {
void *ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
} epoll_data_t;
struct epoll_event {
__uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);主要是epoll_create,epoll_ctl和epoll_wait三個函數。epoll_create函數創建epoll文件描述符,參數size並不是限制了epoll所能監聽的描述符最大個數,只是對內核初始分配內部數據結構的一個建議。返回是epoll描述符。-1表示創建失敗。epoll_ctl 控制對指定描述符fd執行op操作,event是與fd關聯的監聽事件。op操作有三種:添加EPOLL_CTL_ADD,刪除EPOLL_CTL_DEL,修改EPOLL_CTL_MOD。分別添加、刪除和修改對fd的監聽事件。epoll_wait 等待epfd上的io事件,最多返回maxevents個事件。
在 select/poll中,進程只有在調用一定的方法後,內核才對所有監視的文件描述符進行掃描,而epoll事先通過epoll_ctl()來注冊一 個文件描述符,一旦基於某個文件描述符就緒時,內核會採用類似callback的回調機制,迅速激活這個文件描述符,當進程調用epoll_wait() 時便得到通知。
epoll的優點主要是一下幾個方面:
1. 監視的描述符數量不受限制,它所支持的FD上限是最大可以打開文件的數目,這個數字一般遠大於2048,舉個例子,在1GB內存的機器上大約是10萬左 右,具體數目可以cat /proc/sys/fs/file-max察看,一般來說這個數目和系統內存關系很大。select的最大缺點就是進程打開的fd是有數量限制的。這對 於連接數量比較大的伺服器來說根本不能滿足。雖然也可以選擇多進程的解決方案( Apache就是這樣實現的),不過雖然linux上面創建進程的代價比較小,但仍舊是不可忽視的,加上進程間數據同步遠比不上線程間同步的高效,所以也 不是一種完美的方案。
2. IO的效率不會隨著監視fd的數量的增長而下降。epoll不同於select和poll輪詢的方式,而是通過每個fd定義的回調函數來實現的。只有就緒的fd才會執行回調函數。
3.支持電平觸發和邊沿觸發(只告訴進程哪些文件描述符剛剛變為就緒狀態,它只說一遍,如果我們沒有採取行動,那麼它將不會再次告知,這種方式稱為邊緣觸發)兩種方式,理論上邊緣觸發的性能要更高一些,但是代碼實現相當復雜。
4.mmap加速內核與用戶空間的信息傳遞。epoll是通過內核於用戶空間mmap同一塊內存,避免了無畏的內存拷貝。
3、請教Linux下伺服器用select處理一個socket對應的多個客戶端
如果客戶端並發連接數不是很大,比如50個以下,可以用如下模型:建立一個監聽主線程回,循環監聽埠。當有答客戶端連接時,建立客戶端通訊線程,並保留客戶端socket到鏈表中。當客戶端斷開連接時,從socket鏈表中刪除該socket。
4、linux下伺服器程序的幾種基本模型
我總結下來有這么幾種:
單進程提供服務
多進程提供服務
多進程池服務(prefork)
io復用提供服務(select,poll)
epoll(其實也是一種IO復用)
多線程提供服務
多線程池提供服務
信號驅動提供服務
5、linux select 怎麼理解
linux select函數詳解
在Linux中,我們可以使用select函數實現I/O埠的復用,傳遞給 select函數的參數會告訴內核:
•我們所關心的文件描述符
•對每個描述符,我們所關心的狀態。(我們是要想從一個文件描述符中讀或者寫,還是關注一個描述符中是否出現異常)
•我們要等待多長時間。(我們可以等待無限長的時間,等待固定的一段時間,或者根本就不等待)
從 select函數返回後,內核告訴我們一下信息:
•對我們的要求已經做好准備的描述符的個數
•對於三種條件哪些描述符已經做好准備.(讀,寫,異常)
有了這些返回信息,我們可以調用合適的I/O函數(通常是 read 或 write),並且這些函數不會再阻塞.
#include <sys/select.h>
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeval *timeout);
返回:做好准備的文件描述符的個數,超時為0,錯誤為 -1.
首先我們先看一下最後一個參數。它指明我們要等待的時間:
struct timeval{
long tv_sec; /*秒 */
long tv_usec; /*微秒 */
}
有三種情況:
timeout == NULL 等待無限長的時間。等待可以被一個信號中斷。當有一個描述符做好准備或者是捕獲到一個信號時函數會返回。如果捕獲到一個信號, select函數將返回 -1,並將變數 erro設為 EINTR。
timeout->tv_sec == 0 &&timeout->tv_usec == 0不等待,直接返回。加入描述符集的描述符都會被測試,並且返回滿足要求的描述符的個數。這種方法通過輪詢,無阻塞地獲得了多個文件描述符狀態。
timeout->tv_sec !=0 ||timeout->tv_usec!= 0 等待指定的時間。當有描述符符合條件或者超過超時時間的話,函數返回。在超時時間即將用完但又沒有描述符合條件的話,返回 0。對於第一種情況,等待也會被信號所中斷。
6、linux下的select函數是幹嘛的
不是用得很好嗎?精確延時功能。
此外,可以用來判斷讀寫操作是否在指定時間內就緒。
7、Linux的select系統調用如何用在「寫」中
select調用的作用是:同時檢查監聽套接字和客戶連接套接字,一旦select調用指示有活動發生,即返回值大於0,就可以用FD_ISSET來遍歷所有可能的描述符,以檢查是哪個上面有活動發生。
如果是監聽套接字可讀,說明正有一個客戶試圖建立連接,此時,即可調用
accept,並且不用擔心發生阻塞。反之,如果是某個客戶描述符准備好,則說明該描述符上有一個客戶請求需要我們讀取和處理,這時就可以調用recv(),send().
就這樣吧,你自己再看看。
8、Linux中select poll和epoll的區別
select:
下面是select的函數介面:
int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
select
函數監視的文件描述符分3類,分別是writefds、readfds、和exceptfds。調用後select函數會阻塞,直到有描述副就緒(有數據
可讀、可寫、或者有except),或者超時(timeout指定等待時間,如果立即返回設為null即可),函數返回。當select函數返回後,可以
通過遍歷fdset,來找到就緒的描述符。
select目前幾乎在所有的平台上支持,其良好跨平台支持也是它的一個優點。select的一
個缺點在於單個進程能夠監視的文件描述符的數量存在最大限制,在Linux上一般為1024,可以通過修改宏定義甚至重新編譯內核的方式提升這一限制,但
是這樣也會造成效率的降低。
poll:
int poll (struct pollfd *fds, unsigned int nfds, int timeout);
不同與select使用三個點陣圖來表示三個fdset的方式,poll使用一個 pollfd的指針實現。
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events to watch */
short revents; /* returned events witnessed */
};
pollfd結構包含了要監視的event和發生的event,不再使用select「參數-值」傳遞的方式。同時,pollfd並沒有最大數量限制(但是數量過大後性能也是會下降)。 和select函數一樣,poll返回後,需要輪詢pollfd來獲取就緒的描述符。
從上面看,select和poll都需要在返回後,通過遍歷文件描述符來獲取已經就緒的socket。事實上,同時連接的大量客戶端在一時刻可能只有很少的處於就緒狀態,因此隨著監視的描述符數量的增長,其效率也會線性下降。
epoll:
epoll的介面如下:
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
typedef union epoll_data {
void *ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
} epoll_data_t;
struct epoll_event {
__uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
主要是epoll_create,epoll_ctl和epoll_wait三個函數。epoll_create函數創建epoll文件描述符,參數size並不是限制了epoll所能監聽的描述符最大個數,只是對內核初始分配內部數據結構的一個建議。返回是epoll描述符。-1表示創建失敗。epoll_ctl 控制對指定描述符fd執行op操作,event是與fd關聯的監聽事件。op操作有三種:添加EPOLL_CTL_ADD,刪除EPOLL_CTL_DEL,修改EPOLL_CTL_MOD。分別添加、刪除和修改對fd的監聽事件。epoll_wait 等待epfd上的io事件,最多返回maxevents個事件。
在
select/poll中,進程只有在調用一定的方法後,內核才對所有監視的文件描述符進行掃描,而epoll事先通過epoll_ctl()來注冊一
個文件描述符,一旦基於某個文件描述符就緒時,內核會採用類似callback的回調機制,迅速激活這個文件描述符,當進程調用epoll_wait()
時便得到通知。
epoll的優點主要是一下幾個方面:
1.
監視的描述符數量不受限制,它所支持的FD上限是最大可以打開文件的數目,這個數字一般遠大於2048,舉個例子,在1GB內存的機器上大約是10萬左
右,具體數目可以cat
/proc/sys/fs/file-max察看,一般來說這個數目和系統內存關系很大。select的最大缺點就是進程打開的fd是有數量限制的。這對
於連接數量比較大的伺服器來說根本不能滿足。雖然也可以選擇多進程的解決方案(
Apache就是這樣實現的),不過雖然linux上面創建進程的代價比較小,但仍舊是不可忽視的,加上進程間數據同步遠比不上線程間同步的高效,所以也
不是一種完美的方案。
2. IO的效率不會隨著監視fd的數量的增長而下降。epoll不同於select和poll輪詢的方式,而是通過每個fd定義的回調函數來實現的。只有就緒的fd才會執行回調函數。
3.支持電平觸發和邊沿觸發(只告訴進程哪些文件描述符剛剛變為就緒狀態,它只說一遍,如果我們沒有採取行動,那麼它將不會再次告知,這種方式稱為邊緣觸發)兩種方式,理論上邊緣觸發的性能要更高一些,但是代碼實現相當復雜。
4.mmap加速內核與用戶空間的信息傳遞。epoll是通過內核於用戶空間mmap同一塊內存,避免了無畏的內存拷貝。
9、關於select函數在linux下的問題
因為LINUX下的標准輸出stdout,是行緩沖的,緩沖區大小8192位元組是一個典型值.
必須遇到字元'\n'才真正刷新緩沖區輸出到屏幕上,或者輸出緩沖區被填滿也會輸出到屏幕。
我估計,你等足夠長的時間,等你的修改後的程序把輸出緩沖區填滿,會一次性的列印出一大堆abc.
10、Linux下select函數文件描述符狀態的問題
當然是在有輸入或者輸出時文件描述符的讀寫狀態改變咯,比如標准輸入的文件描述符是0,如果用select來等待0號文件描述符,那麼當在鍵盤上敲字元時開始,就是文件描述符的讀寫狀態改變之時,這時select函數就會返回;對於套接字描述符來說也是這樣,用select來等待一個伺服器描述符,那麼當有新的連接請求時(伺服器描述符等待請求時是一個讀描述符,當有新請求時實際上是有一個輸入),伺服器描述符的讀寫狀態改變,select函數返回。順便說一下,檢查哪個文件描述符發生改變,可以用FD_ISSET宏來進行檢測。