2012-05-04 22 views
8

मैं सी ++ में प्रोग्रामिंग कर रहा हूं, लेकिन मैं केवल pthread.h का उपयोग कर रहा हूं, कोई बूस्ट या सी ++ 11 धागे नहीं।सी में थ्रेड पूल कैसे लागू किया जाना चाहिए?

तो मैं धागे का उपयोग करने की कोशिश कर रहा हूं लेकिन मेरे पिछले प्रश्नों में से एक (link) पर आधारित है, यह संभव नहीं लगता है क्योंकि धागे अपने कार्य को पूरा करने के बाद सही समाप्त हो जाते हैं, और थ्रेड- पूल कार्यान्वयन कई कार्यों के लिए इन थ्रेडों का पुन: उपयोग करके थ्रेड-निर्माण ओवरहेड को कम करना है।

तो सी में फोर्क() का उपयोग करने के लिए इसे लागू करने का एकमात्र अन्य तरीका है, और मुख्य से बाल प्रक्रियाओं में पाइप बनाना है? या क्या धागे और उनके माता-पिता के बीच एक पाइप स्थापित करने का कोई तरीका है जिसे मैं नहीं जानता?

अग्रिम में बहुत धन्यवाद!

+0

छिपा धागा निर्माण और कुछ वेक-अप घटना के साथ नौकरियों के एक कतार (समारोह + ऑब्जेक्ट) होने यह करना चाहिए । क्या आप कुछ विशिष्ट व्यवहार की तलाश में हैं? –

+2

तय करें कि आप सी या सी ++ समाधान चाहते हैं या नहीं। चाहे अंतर्निहित लाइब्रेरी pthreads (यानी सी केवल) भाषा से बहुत कम महत्वपूर्ण है जिसके लिए आप थ्रेड पूल प्रदान करना चाहते हैं। –

+0

.. और फिर C++ –

उत्तर

6

हां, आप धागे के बीच thread-safe queue बना सकते हैं। फिर पूल में धागे कूड़े से किसी आइटम को पुनर्प्राप्त करने वाले लूप में बैठे होंगे, जो कुछ भी चाहिए उसे निष्पादित करेंगे, फिर वापस जाकर एक और प्राप्त करेंगे।

यह आमतौर पर सी ++ में थोड़ा आसान/सरल है क्योंकि कुछ इंटरफेस पर सहमत होना थोड़ा आसान है (उदाहरण के लिए, किसी कार्य के लिए कोड निष्पादित करने के लिए अधिभार operator()), लेकिन मौलिक स्तर पर आप सभी एक ही कर सकते हैं सी में चीजें (उदाहरण के लिए, प्रत्येक task कतार में रखी गई संरचना में उस कार्य के लिए कार्य करने के लिए एक फ़ंक्शन में एक पॉइंटर होगा)।

अपने मामले में, चूंकि आप सी ++ का उपयोग कर रहे हैं, हालांकि काम करने के लिए operator() के अधिभार का उपयोग करना संभवतः आसान है। शेष task संरचना (या जिसे आप इसे कॉल करना चुनते हैं) में कोई भी डेटा आवश्यक होगा, आदि

+0

तो आदर्श रूप से, कतार को थ्रेड सुरक्षित होना चाहिए और अधिकतम संख्या के अधिकतम मूल्य के साथ सेमफोर का उपयोग करना होगा धागे के लिए जो मैं उगने जा रहा हूँ, है ना? यह कार्यान्वयन थोड़ा गंदा लगता है ... मुझे कक्षा में encapsulated नहीं, "सादा दृष्टि में बाहर" सही सेटिंग डेटा/कंटेनर महसूस नहीं करते हैं। यही कारण है कि मैंने मास्टर-चाइल्ड_थ्रेड पाइप कार्यान्वयन के बारे में पूछा –

+0

डेटा एन्क्रिप्शन के बराबर अभिभावक-child_PROCESS पाइप रखने का ओवरहेड है? –

+0

@ के-रैन: जिसे मैंने लिंक किया है ("अंतिम कोड" तक स्क्रॉल करें) * * कक्षा में encapsulated है। –

3

POSIX standard से:

int pthread_create(pthread_t *restrict thread, 
    const pthread_attr_t *restrict attr, 
    void *(*start_routine)(void*), void *restrict arg); 

(...) धागा अपने एकमात्र तर्क के रूप में arg साथ start_routine क्रियान्वित बनाई गई है।

तो आप इस समारोह के साथ धागे का एक समूह बनाने चाहिए, और उन सब एक समारोह है कि (जैसे

void *consumer(void *arg) 
{ 
    WorkQueue *queue = static_cast<WorkQueue *>(arg); 

    for (task in queue) { 
     if (task == STOP_WORKING) 
      break; 
     do work; 
    } 
    return WHATEVER; 
} 

कुछ इनपुट के अंत में चला जाता है पर अमल किया है, nSTOP_WORKING आइटम धक्का मन आप कतार जहां n धागे की संख्या है।)

, pthreads एक बहुत ही निम्न स्तर एपीआई कि बहुत कम प्रकार- सुरक्षा प्रदान करता है (सभी डेटा void पी के रूप में पारित हो जाता है ointers)। यदि आप सीपीयू-गहन कार्यों को समानांतर करने का प्रयास कर रहे हैं, तो आप इसके बजाय OpenMP देख सकते हैं।

2

'संभव नहीं लगता है क्योंकि धागे अपने कार्य को पूरा करने के बाद सही समाप्त हो जाते हैं' क्या ??

for(;;){ 
    Task *myTask=theCommonProducerConsumerQueue->pop(); 
    myTask->run(); 
} 

.. कभी भी कुछ भी वापस नहीं लौटाएं, वास्तव में कभी वापस नहीं आते।

+0

मैंने इस पोस्ट से पहले कभी नहीं सोचा था, और न ही मुझे पाथ्रेड नींद के तरीकों के बारे में पता था; इससे पहले धागे की मेरी समझ यह थी कि वे एक शॉट वाली चीजें हैं। –

-1

http://people.clarkson.edu/~jmatthew/cs644.archive/cs644.fa2001/proj/locksmith/code/ExampleTest/threadpool.c

मैं गूगल का इस्तेमाल किया एक जोड़े महीने पहले, आप इसे कोशिश करनी चाहिए।

संपादित करें: ऐसा लगता है कि आप इसके बजाय एक समूह चाहते हैं। मैं उपरोक्त के कुछ मामूली बदलाव के साथ एक बनाने में सक्षम था ताकि कार्यकर्ता ने काम नहीं किया, लेकिन बस धागे में शामिल हो गए।

+0

क्या आपको कोई विचार है कि इस थ्रेडपूल को libevent जैसे ईवेंट लाइब्रेरी में कैसे एकीकृत किया जाए। ऐसा लगता है कि यह अनंत अनंत लूप है जो धागे के लिए काम की प्रतीक्षा करता है। –

2

आपको the source code for libdispatch पर देखने में मदद मिल सकती है, जो ऐप्पल के ग्रैंड सेंट्रल डिस्पैच का आधार है और थ्रेड पूल का उपयोग करता है।

+1

वाह, दिलचस्प। धन्यवाद! –

1

मैं इंटेल से Threaded Building Blocks का उपयोग करके कार्य-कतार/थ्रेडपूल कार्यों को पूरा करने का सुझाव दूंगा। TBB 3.0 का उपयोग कर एक काफी काल्पनिक उदाहरण:

class PoorExampleTask : public tbb::task { 
    PoorExampleTask(int foo, tbb::concurrent_queue<float>& results) 
    : _bar(foo), _results(results) 
    { } 

    tbb::task* execute() { 
     _results.push(pow(2.0, foo)); 
     return NULL; 
    } 

private: 
    int _bar; 
    tbb::concurrent_queue<float>& _results; 
} 

इसलिए की तरह बाद में उपयोग किया:

tbb::concurrent_queue<float> powers; 
for (int ww = 0; ww < LotsOfWork; ++ww) { 
    PoorExampleTask* tt 
     = new (tbb::task::allocate_root()) PoorExampleTask(ww, powers); 
    tbb::task::enqueue(*tt); 
} 

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

  • कोई संबंधित समस्या नहीं^_^