2010-09-29 14 views
17

Birkaç çocuk ileti dizisi oluşturmak için pthread_create kullanın. Bir anda, ana iş parçacığı tüm çocuk dişlerini öldürmek ister ya da bölüm gecikme olur. Bunu bitirmek için hangi işlevi kullanmalıyım? Cevabı google'dan aradım ve pthread_kill gibi işlev aldım. Ama onları öldürmek için çocuk ipliğine hangi sinyali göndermem gerektiğini bilmiyordum. Çalışma ortamım RHEL 5.4 ve programlama dili C'dir.Pthread için, Ana thread'dan çocuk ipini nasıl öldürebilirim?

+2

vay, tüm iş parçacığını öldür, çünkü bir segfault olacak? dalgamı geçiyorsun? Asla böyle bir kodla uğraşmam. –

+1

Gerçekten konuşursak, ana iş parçacığı çıkışları genel nesneler bozulduğunda bulunan çekirdek dökümünü gdb. Bu yüzden bazı çocuk konuları şu anda böyle bir değişken kullanabilir ve ekranımda segment hatası yazdırılır. Her ne kadar mantık doğru ve segment hatalarının programım üzerinde herhangi bir etkisi olmayacaktır, çünkü bitmiştir. – terry

+2

Mantığı düzeltin. Diğer iş parçacıkları hala işe yararsa, neden programı sonlandırmaya çalışıyorsunuz? Eğer 'ana' alanın dışına çıktığında bile diğer nesneler hala bu nesnelere ihtiyaç duyuyorsa, neden ana yığına tahsis edilir? –

cevap

20

pthread_cancel kullanarak bir iş parçacığı "iptal etmek" mümkündür. Bununla birlikte, bu tipik olarak en iyi uygulama değildir, ancak SEGFAULT gibi aşırı koşullar altında makul bir yaklaşımla karşılaşılabilir.

+1

Bu URL'de bir örnek var http://linux.die.net/man/3/pthread_cleanup_push – enthusiasticgeek

+4

Neden pthread_cancel' en iyi uygulama olarak kabul edilmiyor? Ve eğer en iyi uygulama değilse, nedir? – darnir

6

Tüm parçacığı kurtulmak için

int pthread_kill(pthread_t thread, int sig); 

hızlı bir yolu kullanarak, iş parçacığı her birine SIG_TERM göndermesi gerektiğini (ana yanı sıra) çatal() ve çocuk ile devam etmektir.
Değil hiper temiz ... Genelde

if (fork()) exit(0); // deals also with -1... 
24

, gerçekten şiddetle bir çocuk parçacığı öldürmek istemiyoruz, ancak bunun yerine sonlandırmak için sormak istiyorum. Bu şekilde çocuğun güvenli bir yerde bıraktığından ve tüm kaynaklarının temizlendiğinden emin olabilirsiniz.

Genelde, ebeveynin her çocuğa bir "istek isteğini" iletmesine izin vermek için ebeveyn ile çocuk arasında küçük bir paylaşılan durum parçası ile yapıyorum. Bu, her bir çocuk için bir muteks tarafından korunan bir boole değeri olabilir. Çocuk bu değeri periyodik olarak kontrol eder (her döngü tekrarı veya çocuğunuzun ipliğindeki uygun kontrol noktaları). "Quit_request" öğesini true görerek, çocuk iş parçacığı temizler ve pthread_exit numaralı telefonu çağırır. pthread_join çocuk isteğini çıkmak onun denetler ne sıklıkta bağlı olarak biraz zaman alabilir

acquire shared mutex 
set quit_request to true 
pthread_join the child 

: Üst tarafta

, "kill_child" rutin şuna benzer. Tasarımınızın gecikme ne olursa olsun işleyebileceğinden emin olun.

+0

Genellikle iş parçacıkları arasında paylaşılan herhangi bir belleği değiştirmeden önce bir mutex elde etmek için iyi bir uygulama olsa da, bunun sıfır olmayan (veya yanlış) durum için kontrol edilen tek bir bayrak olduğu gerçeği, gerçekten ihtiyacınız olmayan anlamına gelir. Bir muteks kapmak için. Bu durumda, veri tutarlılık perspektifinden yanlış gidebilecek pek fazla şey yoktur. –

+2

@Brent: [Bu soru] (http://stackoverflow.com/questions/21183261/is-a-race-condition-possible-when-only-one-thread-writes-to-a-bool-variable-in -c), bir kez yazılan tek bir bayrakın bile, derleyici optimizasyonlarından sonra bir yarış durumuna yol açabileceği bir örneği gösterir. – dshepherd

+0

Güzel, bu harika çalışıyor. – djthoms

2

Tüm program için global bir değişken kullanabilirsiniz.

int _fCloseThreads;

İpliklerin yürütmeyi bırakmasını istediğinizde 1'e ayarlayın. İş parçacığı bu değişkeni "döngüsünde" kontrol etsin ve 1'e ayarlandığında güzelce çıksın. Bunu bir muteks ile korumaya gerek yok.

İpliklerin çıkmasını beklemeniz gerekir. Birleştirme kullanabilirsiniz. Başka bir yöntem, bir iş parçacığı iş parçacığı girdikten sonra sayaç çıkması ve sonra sayaçtan çıktığında sayım yapmaktır. Sayacın bir çeşit küresel olması gerekecek. Tezgahta gcc atomik ops kullanın. Ana iş parçacığı, fCloseThreads ayarladıktan sonra sayaçta, döngü yaparak, uyuyarak ve sayımı denetleyerek sıfıra kadar bekleyebilir.

Son olarak, pthread_cleanup_push ve pop'unu kontrol edebilirsiniz. Bir iş parçacığının kodunda herhangi bir yeri iptal etmesine izin veren bir modeldir (longjump kullanır) ve sonra threadproc'dan çıkmadan önce bir son temizleme işlevini çağırır. Temel olarak threadproc'unuzun üst kısmına cleanup_push ve altta cleanup_pop koyun, bir gevşeme fonksiyonu oluşturun ve sonra belirli iptal etme noktalarında pthread_cancel() öğesine yapılan bir çağrıyla iptal edilen bir thread, threadproc'a geri dönecek ve gevşeme işlevini çağıracaktır.

+1

http://linux.die.net/man/3/pthread_cleanup_push bir örnektir. – enthusiasticgeek

İlgili konular