2010-07-19 16 views
7

तो मुझे सरल कर्ल वर्ग करने वाले वर्कर थ्रेड का एक गुच्छा मिला है, प्रत्येक कार्यकर्ता धागे का अपना कर्ल आसान हैंडल है। वे यादृच्छिक वेबसाइटों पर केवल हेड लुकअप कर रहे हैं। मल्टी थ्रेडेड एसएसएल को here दस्तावेज के रूप में सक्षम करने के लिए फ़ंक्शन लॉकिंग भी मौजूद हैं। सब कुछ 2 वेब पृष्ठों ilsole24ore.com को छोड़कर काम कर रहा है (उदाहरण के नीचे देखा जाता है), और ninemsn.com.au/, वे कभी कभी SEG उत्पादन के रूप में उत्पादन का पता लगाने में दिखाया गया है यहाँlibcurl में सेगमेंटेशन गलती, multithreaded

#0 *__GI___libc_res_nquery (statp=0xb4d12df4, name=0x849e9bd "ilsole24ore.com", class=1, type=1, answer=0xb4d0ca10 "", anslen=1024, answerp=0xb4d0d234, 
     answerp2=0x0, nanswerp2=0x0, resplen2=0x0) at res_query.c:182 
    #1 0x00434e8b in __libc_res_nquerydomain (statp=0xb4d12df4, name=0xb4d0ca10 "", domain=0x0, class=1, type=1, answer=0xb4d0ca10 "", anslen=1024, 
     answerp=0xb4d0d234, answerp2=0x0, nanswerp2=0x0, resplen2=0x0) at res_query.c:576 
    #2 0x004352b5 in *__GI___libc_res_nsearch (statp=0xb4d12df4, name=0x849e9bd "ilsole24ore.com", class=1, type=1, answer=0xb4d0ca10 "", anslen=1024, 
     answerp=0xb4d0d234, answerp2=0x0, nanswerp2=0x0, resplen2=0x0) at res_query.c:377 
    #3 0x009c0bd6 in *__GI__nss_dns_gethostbyname3_r (name=0x849e9bd "ilsole24ore.com", af=2, result=0xb4d0d5fc, buffer=0xb4d0d300 "\177", buflen=512, 
     errnop=0xb4d12b30, h_errnop=0xb4d0d614, ttlp=0x0, canonp=0x0) at nss_dns/dns-host.c:197 
    #4 0x009c0f2b in _nss_dns_gethostbyname2_r (name=0x849e9bd "ilsole24ore.com", af=2, result=0xb4d0d5fc, buffer=0xb4d0d300 "\177", buflen=512, 
     errnop=0xb4d12b30, h_errnop=0xb4d0d614) at nss_dns/dns-host.c:251 
    #5 0x0079eacd in __gethostbyname2_r (name=0x849e9bd "ilsole24ore.com", af=2, resbuf=0xb4d0d5fc, buffer=0xb4d0d300 "\177", buflen=512, result=0xb4d0d618, 
     h_errnop=0xb4d0d614) at ../nss/getXXbyYY_r.c:253 
    #6 0x00760010 in gaih_inet (name=<value optimized out>, service=<value optimized out>, req=0xb4d0f83c, pai=0xb4d0d764, naddrs=0xb4d0d754) 
     at ../sysdeps/posix/getaddrinfo.c:531 
    #7 0x00761a65 in *__GI_getaddrinfo (name=0x849e9bd "ilsole24ore.com", service=0x0, hints=0xb4d0f83c, pai=0xb4d0f860) at ../sysdeps/posix/getaddrinfo.c:2160 
    #8 0x00917f9a in ??() from /usr/lib/libkrb5support.so.0 
    #9 0x003b2f45 in krb5_sname_to_principal() from /usr/lib/libkrb5.so.3 
    #10 0x0028a278 in ??() from /usr/lib/libgssapi_krb5.so.2 
    #11 0x0027eff2 in ??() from /usr/lib/libgssapi_krb5.so.2 
    #12 0x0027fb00 in gss_init_sec_context() from /usr/lib/libgssapi_krb5.so.2 
    #13 0x00d8770e in ??() from /usr/lib/libcurl.so.4 
    #14 0x00d62c27 in ??() from /usr/lib/libcurl.so.4 
    #15 0x00d7e25b in ??() from /usr/lib/libcurl.so.4 
    #16 0x00d7e597 in ??() from /usr/lib/libcurl.so.4 
    #17 0x00d7f133 in curl_easy_perform() from /usr/lib/libcurl.so.4 

से पता चला मेरे समारोह तरह दिखता है गलती इस

int do_http_check(taskinfo *info,standardResult *data) 
{ 
    standardResultInit(data); 

    char errorBuffer[CURL_ERROR_SIZE]; 

    CURL *curl; 
    CURLcode result; 

    curl = curl_easy_init(); 

    if(curl) 
    { 
     //required options first 
     curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer); 
     curl_easy_setopt(curl, CURLOPT_URL, info->address.c_str()); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data->body); 
     curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, writer); 
     curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &data->head); 
     curl_easy_setopt(curl, CURLOPT_DNS_USE_GLOBAL_CACHE,0); 
     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30); 
     curl_easy_setopt(curl, CURLOPT_NOSIGNAL,1); 
     curl_easy_setopt(curl, CURLOPT_NOBODY,1); 
     curl_easy_setopt(curl, CURLOPT_TIMEOUT ,240); 

     //optional options 
     if(info->options.follow) 
     { 
      curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); 
      curl_easy_setopt(curl, CURLOPT_MAXREDIRS, info->options.redirects); 
     } 

     result = curl_easy_perform(curl); 

     if (result == CURLE_OK) 
     { 
      data->success = true; 
      curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&data->httpMsg); 
      curl_easy_getinfo(curl,CURLINFO_REDIRECT_COUNT,&data->numRedirects); 
      data->msg = "OK"; 
     } 
     else 
     { 
      ... handle error 
     } 


    return 1; 
} 

अब, जब मैं किसी भी धागे के बिना फ़ंक्शन को कॉल करें, बस इसे मुख्य रूप से यह कभी नहीं टूटता है बुला, तो मैं सोच रहा था इसके धागे से जुड़ा, या हो सकता है कि कैसे डेटा वापस संरचना लौटे किया जा रहा है, लेकिन क्या से मैं ट्रेस में देखा गया ऐसा लगता है कि easy_perform() कॉल में गलती उत्पन्न होती है, और यह मुझे भ्रमित करती है। तो अगर किसी के पास कोई विचार है तो मुझे आगे कहां देखना चाहिए, यह सबसे उपयोगी होगा, धन्यवाद।

उत्तर

13

libcurl to Multi-Threading में समर्पित एक पूरा अनुभाग है।

पहले बुनियादी नियम है कि आप एक libcurl संभाल का हिस्सा कभी नहीं होना चाहिए के बीच एक से अधिक थ्रेड (यह आसान या बहु या जो कुछ भी हो सकता है) है। एक समय में केवल एक थ्रेड में एक हैंडल का उपयोग करें।

libcurl पूरी तरह से थ्रेड सुरक्षित है, दो मुद्दों को छोड़कर: सिग्नल और एसएसएल/टीएलएस हैंडलर। के लिए सिग्नल का उपयोग समय समाप्त होता है (DNS लुकअप के दौरान) - जब सी-एरेस समर्थन के बिना बनाया गया था और विंडोज पर नहीं।

आप एक्सेस कर रहे हैं HTTPS या FTPS एक मल्टी-थ्रेडेड ढंग से यूआरएल, आप तो निश्चित रूप से उपयोग कर रहे हैं अंतर्निहित एसएसएल पुस्तकालय मल्टी-थ्रेडेड और उन libs इस मुद्दे पर अपने स्वयं के आवश्यकताओं हो सकता है। असल में, आपको इसे एक या दो फ़ंक्शंस प्रदान करने की आवश्यकता है ताकि इसे ठीक से कार्य करने की अनुमति मिल सके। सभी विवरण के लिए, यह देखें:

OpenSSL

http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION

GNUTLS

http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html

एनएसएस

धागा सुरक्षित पहले से ही आवश्यक कुछ भी बिना होने का दावा किया है।

यास्ल

आवश्यक क्रियाएं अज्ञात हैं।

एकाधिक धागे का उपयोग करते समय आपको सभी हैंडल के लिए CURLOPT_NOSIGNAL विकल्प 1 पर सेट करना चाहिए।सब कुछ होगा या ठीक समय पर काम कर सकता है सिवाय इसके कि टाइमआउट को DNS लुकअप के दौरान सम्मानित नहीं किया जाता है - जिसे आप सी-एरेस समर्थन के साथ libcurl बनाकर काम कर सकते हैं। सी-एरेस एक पुस्तकालय है जो असीमित नाम हल करता है। कुछ प्लेटफ़ॉर्म पर, libcurl बस फ़ंक्शन ठीक से बहु-थ्रेडेड कार्य नहीं करेगा जब तक यह विकल्प सेट न हो।

यह भी ध्यान दें कि CURLOPT_DNS_USE_GLOBAL_CACHE थ्रेड-सुरक्षित नहीं है।

+0

हाँ, मैंने कर्ल का वह हिस्सा पढ़ा है, और मेरा कार्यक्रम वहां से सभी दिशानिर्देशों का पालन कर रहा है। लेकिन मैंने समस्या को हल किया है और इसकी गलती नहीं है, यह सिर्फ डीबगर था जो इंगित कर रहा था। मैंने कर्ल के बारे में कुछ नई चीजें सीखीं, वैसे भी धन्यवाद। – Mogwai

0

error: longjmp causes uninitialized stack frame में उल्लेख किया है, नवीनतम libcurl संस्करणों (> = 7.32.0) Debian/Ubuntu के खजाने में इन समस्याओं को हल करने के लिए एक नया बहु समाधानकर्ता होते हैं। सी एरेस समर्थन एक अच्छा समाधान नहीं है:

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=570436#74

'असली समस्या यह है कि सी एरेस अभी तक gethostby * कार्यों (उदाहरण के लिए यह बहुस्त्र्पीय डीएनएस का समर्थन नहीं करता) और सक्षम बनाने के लिए एक पूरी प्रतिस्थापन नहीं है यह स्टॉक libcurl पैकेज में एक अच्छा कदम नहीं हो सकता है (ध्यान दें कि ये दोनों कर्ल और सी-एरेस के अपस्ट्रीम लेखक के शब्द हैं, मेरा नहीं)। "-

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