2012-04-16 15 views
10

मैंने चारों ओर बिखरी हुई जानकारी के बिट्स को देखा है, लेकिन मुझे एक अंतिम उत्तर नहीं मिल रहा है। आप कर्नेल में ज़ोंबी थ्रेड कैसे साफ करते हैं?कर्नेल में धागे को संभालने का सही तरीका?

बस सुनिश्चित करने के लिए, और कर्नेल में धागे को संभालने का अंतिम सही तरीका तैयार करने के लिए, मैं इस सवाल को अधिक व्यापक रूप से पूछना चाहता हूं। लिनक्स कर्नेल में थ्रेड कैसे बनाते हैं, समाप्त करते हैं और साफ करते हैं?

क्या मैं अब तक किया है इस:

thread_func: 
    exited = 0; 
    while (!must_exit) 
     do stuff 
    exited = 1; 
    do_exit(0) 

init_module: 
    must_exit = 0; 
    exited = 1; 
    kthread_run(thread_func, ...) /* creates and runs the thread */ 

cleanup_module: 
    must_exit = 1; 
    while (!exited) 
     set_current_state(TASK_INTERRUPTIBLE); 
     msleep(1); 
    /* How do I cleanup? */ 

निकटतम बात मैं सफाई समाधान के लिए मिल गया है release_task है, लेकिन मैं कहीं भी इसके बारे में बात भी नहीं मिला। मैंने कल्पना की है कि थ्रेड फ़ंक्शंस kthread_create, kthread_run आदि हैं, kthread_join या kthread_wait होना चाहिए, लेकिन वहां नहीं था। do_wait भी लग रहा था, लेकिन यह struct task_struct * नहीं लेता है।

इसके अलावा, मुझे यकीन नहीं है कि do_exit एक अच्छा विचार है, या यदि आवश्यक हो तो। क्या कोई कृपया न्यूनतम स्केच के साथ आ सकता है कि कैसे एक kthread बनाया जाना चाहिए, समाप्त और साफ किया जाना चाहिए?

+2

मुझे याद है कि एक kthread_stop है, या kthread_should_stop, ऐसा कुछ है। –

+0

@ मार्टिनजम्स, जिस तरह से मैंने समझा, आप या तो स्वयं से बाहर निकलें ('do_exit' का उपयोग करके) या 'kthread_should_stop'' मतदान करें जब तक कि कोई (' cleanup_module') 'kthread_stop'' कॉल न करे। मुझे कहीं भी यह नहीं मिला कि 'kthread_stop' भी धागे को साफ करता है या नहीं। मुझे आश्चर्य की बात यह है कि, अगर लोग (इंटरनेट पर) 'do_exit' या जो कुछ भी इस्तेमाल करते हैं, तो' do_exit' के बाद थ्रेड को साफ़ करने का कोई तरीका नहीं होना चाहिए? – Shahbaz

+0

वैसे, [यह] (http://lwn.net/Articles/65178/) मैं तब कहता हूं जब मैं कहता हूं कि मैं एक निर्णायक उत्तर तक नहीं पहुंच सकता। वहां बहुत सारी विवादित चीजें हैं। – Shahbaz

उत्तर

11

ऐसा करने के "सही" तरीकों में से एक यह है कि यह आपके थ्रेड फ़ंक्शन को kthread_should_stop पर जांचने के लिए है, और अगर इसे रोकने की आवश्यकता है तो बस वापस लौटें।

आपको do_exit पर कॉल करने की आवश्यकता नहीं है, और यदि आप मॉड्यूल निकास फ़ंक्शन से kthread_stop का इरादा रखते हैं, तो आपको शायद नहीं करना चाहिए।

आप (लिनक्स कर्नेल 3.3.1 से उद्धरण) kernel/kthread.c में kthread_create_on_node के लिए दस्तावेज़ को देखकर यह देख सकते हैं:

/**
* kthread_create_on_node - एक kthread पैदा करते हैं।
* @threadfn: सिग्नल_पेंडिंग (वर्तमान) तक चलने वाला फ़ंक्शन।
* @ डेटा: @threadfn के लिए डेटा पीआरटी।
* @ नोड: मेमोरी नोड संख्या।
* @namefmt: धागे के लिए printf-style name।
*
* विवरण: यह सहायक कार्य कर्नेल
* थ्रेड बनाता है और नाम देता है। थ्रेड बंद हो जाएगा:
* शुरू करने के लिए wake_up_process() का उपयोग करें। Kthread_run() भी देखें।
*
* यदि थ्रेड किसी विशेष सीपीयू पर बाध्य होने जा रहा है, तो अपने नोड
* @ नोड में, kthread स्टैक के लिए NUMA एफ़िनिटी प्राप्त करने के लिए, या फिर -1 दें।
* जब जागृत हो जाता है, तो धागा @ थ्रेडफन() को @data के साथ
* तर्क के रूप में चलाएगा। @threadfn() do_exit (फोन या तो कर सकते हैं) सीधे अगर यह एक
* जिसके लिए कोई भी kthread_stop फोन करेगा() स्टैंडअलोन धागा, या
* वापसी है जब 'kthread_should_stop()' सच है (जिसका अर्थ है
* kthread_stop() को कॉल किया गया है)। वापसी मान शून्य
* या एक नकारात्मक त्रुटि संख्या होना चाहिए; यह kthread_stop() को पारित किया जाएगा।
*
* एक कार्य_स्ट्रक्चर या ERR_PTR (-ENOMEM) देता है।
*/

ए 'मिलान "टिप्पणी kthread_stop के लिए मौजूद है:

तो threadfn() do_exit() कॉल कर सकते हैं ही, फोन करने वाले यह सुनिश्चित करना चाहिए task_struct दूर नहीं जा सकते।

(और मुझे यकीन है कि कैसे आप ऐसा नहीं कर रहा हूँ - शायद एक get_task_struct साथ struct_task को पकड़ने में।)

आप एक धागा निर्माण आप की तरह कुछ मिल जाएगा के रास्ते चलना हैं:

kthread_create           // macro in kthread.h 
    -> kthread_create_on_node        // in kthead.c 
    -> adds your thread request to kthread_create_list 
    -> wakes up the kthreadd_task 

kthreadd_taskreset_init में init/main.c में स्थापित किया गया है। यह (kthread.c से) kthreadd समारोह

kthreadd             // all in kthread.c 
    -> create_kthread 
    -> kernel_thread(kthread, your_kthread_create_info, ...) 

चलाता है और kthread समारोह में ही करता है:

kthread 
    -> initialization stuff 
    -> schedule() // allows you to cancel the thread before it's actually started 
    -> if (!should_stop) 
    -> ret = your_thread_function() 
    -> do_exit(ret) 

... तो अगर your_thread_function बस देता है, do_exit अपनी वापसी मान के साथ बुलाया जाएगा। इसे स्वयं करने की ज़रूरत नहीं है।

+0

खैर, कार्य संरचना एक वैश्विक चर है, इसलिए यह कहीं भी नहीं जा सकती है। लेकिन, इसका मतलब यह है कि यदि स्टैंडअलोन थ्रेड 'do_exit() '(और इसलिए' kthread_stop' 'नहीं कहता है तो उसे क्लीनअप की आवश्यकता नहीं होगी? – Shahbaz

+0

यह जगह जा सकता है। यदि कार्य जिस कार्य को संदर्भित करता है वह पूरी तरह से किया जाता है, और कार्य संरचना निकास पथ से मुक्त हो जाती है, तो आपके मॉड्यूल डेटा में आपके पास प्रतिलिपि एक खतरनाक सूचक की तरह होती है - आप इसका उपयोग नहीं कर सकते हैं। – Mat

+0

और हां, यदि आप अपने धागे को 'kthread_stop'' का इरादा नहीं रखते हैं, तो यह 'do_exit' को कॉल कर सकता है और सामान्य सफाई हो जाएगी। _But_ अगर किसी भी तरह आपका धागा आपके मॉड्यूल को बाहर निकालने का प्रबंधन करता है, तो आप परेशानी में हैं। – Mat

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