2011-11-02 17 views
12

का चयन करें, मैं अपने सिस्टम के लिए FD_SETSIZE मैक्रो मान को बढ़ाना चाहता हूं। क्या FD_SETSIZE को बढ़ाने का कोई तरीका है इसलिए चयन विफल नहीं होगाFD_SETSIZE की बढ़ती सीमा और

+0

हाँ, मेरे मामले में मुझे इसकी आवश्यकता 2048 है। क्या इसे सेट करने का कोई तरीका है? –

+0

क्योंकि मैं उस कनेक्शन के समर्थन के लिए अपनी सर्वर सीमा को बढ़ाना चाहता हूं। –

+2

कोई अपराध नहीं, लेकिन 'FD_SETSIZE' बढ़ाने के बारे में सोचना एक बहुत ही मूर्ख बात है। 2048 समवर्ती कनेक्शन (या इसके बजाए, उससे अधिक) उस सीमा के भीतर अच्छी तरह से है जहां 'epoll_wait' दोनों' चयन 'और' पोल 'दोनों से काफी बेहतर प्रदर्शन करता है क्योंकि इसे हर बार 8 किलोबाइट डेटा कॉपी करने की आवश्यकता नहीं होती है और इसकी आवश्यकता नहीं होती है हर बार दो हजार से अधिक वर्णनकर्ताओं को फिर से शुरू करने के लिए। – Damon

उत्तर

8

मानकों के अनुसार, FD_SETSIZE बढ़ाने का कोई तरीका नहीं है। कुछ कार्यक्रमों और पुस्तकालयों (libevent मन में आता है) fd_set वस्तु के लिए अतिरिक्त जगह का आवंटन और मूल्यों FD_* मैक्रो में किए गए FD_SETSIZE से बड़ा पारित करके इस के आसपास काम करने की कोशिश, लेकिन यह एक बहुत बुरा विचार है, क्योंकि मजबूत कार्यान्वयन सीमा की जाँच प्रदर्शन पर हो सकता है तर्क और निरस्त अगर यह सीमा से बाहर है।

मैं एक वैकल्पिक समाधान है कि हमेशा काम करना चाहिए (हालांकि यह मानकों के द्वारा करने के लिए आवश्यक नहीं है) है। एक fd_set ऑब्जेक्ट के बजाय, अधिकतम सरणी रखने के लिए पर्याप्त रूप से उनमें से एक सरणी आवंटित करें, फिर सेट तक पहुंचने के लिए FD_SET(fd%FD_SETSIZE, &fds_array[fd/FD_SETSIZE]) आदि का उपयोग करें।

+0

मैं एक तृतीय पक्ष लाइब्रेरी का उपयोग कर रहा हूं। क्या आपके सुझाव के साथ कोड को पूल करने या पूल के साथ बदलने का कोई आसान तरीका है? –

+3

यह झूठा जवाब है। कृपया http://support.microsoft.com/kb/111855 – dns

+5

@dns पढ़ें: यह झूठी प्रलेखन है। :-) कृपया http://pubs.opengroup.org/onlinepubs/9699919799/functions/pselect.html पढ़ें। ठीक है, एक तरफ मजाक कर, कृपया बताएं कि आप क्या सोचते हैं मेरे जवाब के बारे में "झूठा" है। –

12

मैं भी यदि संभव हो तो poll उपयोग करने का सुझाव। और वहाँ libevent या libev (या जीटीके से Glib की घटना क्षमताओं, या QtCore, आदि) है जो आप की मदद करनी चाहिए जैसे कई "घटना" प्रसंस्करण पुस्तकालयों में मौजूद हैं। epoll जैसी चीजें भी हैं। और आपकी समस्या C10k

+1

हां। मुझे लगता है कि यह अंतिम जवाब है। यदि आपके मॉनीटर किए गए वर्णनकर्ता में से एक लिनक्स के नीचे 1024 से अधिक गिरता है, तो आपको fd_set संरचना (और वैसे भी आगे की समस्याओं का जोखिम) के माध्यम से हैक करना होगा, या मतदान का उपयोग करना बेहतर होगा ... बेहतर। –

1

वास्तव में आईएस विंडोज़ पर FD_SETSIZE बढ़ाने का एक तरीका है। इसके winsock.h में परिभाषित किया गया है और माइक्रोसॉफ्ट खुद को प्रति आप बस इसे परिभाषित करते हुए यह वृद्धि कर सकते हैं इससे पहले कि आप winsock.h

http://support.microsoft.com/kb/111855

शामिल मैं यह सब समय करते हैं और कोई समस्या नहीं सबसे बड़ा मान मैं का इस्तेमाल किया है था पड़ा है एक सर्वर के लिए 5000 के आसपास मैं

+4

बीएसडी और विंडोज़ FD_SETSIZE सेट होने की अनुमति देता है। लिनक्स नहीं जहां fd_set आंतरिक आकार वास्तव में __FD_SETSIZE द्वारा सेट किया गया है जो कि 1024 तक हार्डकोड किया गया है। लिनक्स के लिए, मतदान का उपयोग करना बेहतर है क्योंकि स्लेसेट पहले 1024 वर्णक से अधिक के लिए काम नहीं कर सकता है। वास्तव में यह लिनक्स पर काम करने के लिए प्रतीत होता है लेकिन आवंटित fd_set के बाहर बिट्स का उपयोग करेगा, निश्चित रूप से भ्रष्ट ढेर और दुर्घटनाओं का कारण बन जाएगा। यही कारण है कि वर्तमान जवाब खुद को ढेर पर अधिक जगह आवंटित करना है जो बहुत सुंदर नहीं है। –

+1

प्रश्न लिनक्स से संबंधित है, विंडोज़ नहीं। – mpromonet

8

विकास हो रहा था यह बेहतर है (और आसान) चुनाव के साथ बदलना होगा। आम तौर पर चुनाव() का चयन के लिए एक सरल ड्रॉप-में प्रतिस्थापन() है और FD_SETSIZE की 1024 सीमित नहीं है ...

fd_set fd_read; 
int id = 42; 
FD_ZERO(fd_read); 
FD_SET(id, &fd_read); 
struct timeval tv; 
tv.tv_sec = 5; 
tv.tv_usec = 0; 
if (select(id + 1, &fd_read, NULL, NULL, &tv) != 1) { 
    // Error. 
} 

हो जाता है:

struct pollfd pfd_read; 
int id = 42; 
int timeout = 5000; 
pfd_read.fd = id; 
pfd_read.events = POLLIN; 
if (poll(&pfd_read, 1, timeout) != 1) { 
    // Error 
} 

आप सर्वेक्षण में शामिल करने की जरूरत है। पराग संरचना के लिए एच।

आप के साथ ही तो पढ़ा Pollin के रूप में की घटनाओं ध्वज सेट लिखने के लिए की जरूरत है | POLLOUT।

6

यह sys/select.h शामिल करने से पहले FD_SETSIZE overiding __FD_SETSIZE (sys/types.h में परिभाषित) को बढ़ाने के लिए संभव है।

ऐसे ही आगे बढ़ने हम सेट कर सकते हैं FD_SETSIZE2048 रहे हैं:

#include <sys/types.h> 
#undef __FD_SETSIZE 
#define __FD_SETSIZE 2048 
#include <sys/select.h> 
#include <stdio.h> 

int main() 
{ 
    printf("FD_SETSIZE:%d sizeof(fd_set):%d\n",FD_SETSIZE,sizeof(fd_set)); 
    return 0; 
} 

प्रिंट होगा:

FD_SETSIZE: 2048 sizeof (fd_set): 128

लेकिन अगर FD_SETSIZE है संशोधित मान के बाद, sizeof (fd_set) 256 (2048/8) होना चाहिए और 128 (1024/8) नहीं होना चाहिए। ऐसा इसलिए है क्योंकि sys/types.h पहले से ही 1024 के साथ fd_set को परिभाषित करता है।

#include <sys/select.h> 
#include <stdio.h> 

#define EXT_FD_SETSIZE 2048 
typedef struct 
{ 
    long __fds_bits[EXT_FD_SETSIZE/8/sizeof(long)]; 
} ext_fd_set; 

int main() 
{ 
    ext_fd_set fd; 
    int s; 
    printf("FD_SETSIZE:%d sizeof(fd):%ld\n", EXT_FD_SETSIZE, sizeof(fd)); 
    FD_ZERO(&fd); 
    while (((s=dup(0)) != -1) && (s < EXT_FD_SETSIZE)) 
    { 
     FD_SET(s, &fd); 
    } 
    printf("select:%d\n", select(EXT_FD_SETSIZE,(fd_set*)&fd, NULL, NULL, NULL)); 
    return 0; 
} 

यह प्रिंट:

FD_SETSIZE: 2048 sizeof (एफडी)


आदेश एक बड़ा fd_set का उपयोग करने के अलावा, यह इस तरह एक विस्तारित एक परिभाषित करना संभव है: 256

का चयन करें: 2045


1024 से अधिक दायरलेखकों को खोलने के लिए, उदाहरण ulimit -n 2048 के लिए उपयोग सीमा को बढ़ाने के लिए आवश्यक है।

+1

यह सही उत्तर है। –

+1

यह संभावित रूप से खतरनाक है। मानक अनुपालन के (वैध, आईएमओ) मुद्दे में प्रवेश किए बिना, एक और स्पष्ट उपयोग केस है जहां यह असफल हो सकता है, और वह तब होता है जब सिस्टम परिभाषित FD_SETSIZE का उपयोग करने के लिए संकलित लाइब्रेरी के विरुद्ध लिंक किया जाता है। 'मतदान() 'का उपयोग सही दृष्टिकोण है। – edam

संबंधित मुद्दे