2012-04-16 27 views
10

Her yerde dağınık bilgi parçaları gördüm, ancak bir son cevabı göremiyorum. Çekirdeğindeki zombi ipini nasıl temizlersin?Çekirdekdeki iş parçacıklarının uygun şekilde işlenmesi?

Sadece çekirdeğindeki iplikleri işlemek için kesin bir yol ve emin olmak için, bu soruyu daha geniş bir şekilde sormak istiyorum. Linux çekirdeğindeki bir iş parçacığını nasıl oluşturur, sonlandırır ve temizlersiniz?

Ne var bugüne kadar şudur:

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? */ 

ben temizleme solüsyonu bulduk yakın şey release_task, ama bu konuda konuşmak yerde bulamadık. İş parçacığı işlevleri kthread_create, kthread_run vb olduğundan beri hayal ettim, bir kthread_join veya kthread_wait olmalıdır, ancak yoktu. do_wait da olası görünüyordu, ancak struct task_struct * almıyor. Ayrıca, do_exit'un iyi bir fikir olup olmadığından veya gerekmediğinden emin değilim. Birisi bir kthread'in nasıl yaratılması, sonlandırılması ve temizlenmesi gerektiğine dair en ufak bir taslak çizebilir mi?

+2

Kthread_stop veya kthread_should_stop gibi bir şey olduğunu hatırlıyorum. –

+0

@MartinJames, anladığım kadarıyla, ("do_exit" kullanarak) kendinizden çıkın ya da birileri ('cleanup_module')' kthread_stop' çağırsıncaya kadar '' kthread_should_stop'' komutunu verin. "Kthread_stop" un da ipliği temizleyip temizlemediğini söyleyen bir yer bulamadım. Beni şaşırtan şey şudur: Eğer insanlar (internette) 'do_exit' ya da her neyse kullanma önerisinde bulunurlarsa, 'do_exit' sonrası iş parçacığını temizlemenin bir yolu olmamalı mıdır? – Shahbaz

+0

Bu arada, [bu] (http://lwn.net/Articles/65178/) söylediğim şey hakkında konuştuğum şey, kesin bir cevaba ulaşamıyorum. Orada çok fazla çatışan şey var. – Shahbaz

cevap

11

Bunu yapmanın "doğru" yollarından biri, iş parçacığınızın işlevinin kthread_should_stop olup olmadığını denetlemesi ve yalnızca durdurulması gerekirse geri dönmesidir.

do_exit numaralı telefonu aramanıza gerek yoktur ve modül çıkış işlevinden kthread_stop ürününü kullanmayı düşünüyorsanız, büyük ihtimalle bunu yapmamalısınız.

Sen (Linux çekirdeği 3.3.1 den ekstresi) kernel/kthread.c içinde kthread_create_on_node belgelerine bakarak bunu görebilirsiniz:

/**
* kthread_create_on_node - Bir kthread oluşturun.
* @threadfn: signal_pending (geçerli) değerine kadar çalışacak işlev.
* @data: data ptr for @threadfn.
* @node: bellek düğümü numarası.
* @namefmt: iş parçacığı için printf stili adı.
*
* Açıklama: Bu yardımcı işlev, bir çekirdek
* iş parçacığı oluşturur ve adlandırır. İş parçacığı durdurulacak:
* 'u başlatmak için wake_up_process() kullanın. Ayrıca bakınız kthread_run().
*
* iplik belirli bir işlemci üzerinde bağlı olacak ise, kendi düğümünü verir
* @node olarak vermek başka kthread yığını için numa afinite almak ya da -1.
* Uyandığında, thread @threadfn() işleviyle @data değerini
* argümanında çalıştıracaktır. 'Kthread_should_stop()' true olduğunda @threadfn() (bir kimsenin) (kthread_stop arayacak için
* bağımsız iplik veya
* dönüş ise doğrudan varsa) do_exit (çağırabilir ya Yani
* kthread_stop() çağrıldı). Dönüş değeri
* veya negatif bir hata numarası olmalıdır; kthread_stop() öğesine aktarılacak.
*
* Bir task_struct veya ERR_PTR (-ENOMEM) döndürür. */


Bir "eşleştirme" yorum kthread_stop için mevcut: threadfn()) kendisini do_exit (diyebilir miyim

, arayan task_struct uzağa gidemez sağlamalıdır.

(Ve ben bunu nasıl emin değilim - muhtemelen get_task_struct ile struct_task tutarak.)

Eğer böyle bir şey çıkacak bir iplik oluşturma yolunu yürürseniz:

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 yılında init/main.c yılında kurulmuştur. O (kthread.c itibaren) kthreadd fonksiyonunu

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

çalışır Ve kthread işlevi kendisi yapar:

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) 

... Yani your_thread_function basitçe dönerse, do_exit dönüş değeri ile çağrılır. Bunu kendin yapmana gerek yok.

+0

Görev yapısı genel bir değişkendir, bu yüzden hiçbir yere gidemez. Fakat bu, bağımsız iş parçacığı 'do_exit()' olarak adlandırılırsa (ve bu nedenle 'kthread_stop' olarak adlandırılmamalıdır) temizleme gerektirmezse bu mu anlamına gelir? – Shahbaz

+0

Yerlere gidebilir. Bu görev yapısının başvurduğu görev tamamen yapılırsa ve görev yapısı çıkış yolu tarafından serbest bırakılırsa, modül verilerinizdeki kopya bir sallanan işaretçi gibidir - bunu kullanamazsınız. – Mat

+0

Ve evet, eğer 'kthread_stop' iş parçacığı niyetinde değilseniz,' do_exit 'çağırabilir ve normal temizleme gerçekleşir. _But_ iş parçacığınızın bir şekilde modülünüzü geçmeyi başarırsa, başınız dertte demektir. – Mat

İlgili konular