2012-07-05 10 views
6

kernel 2.4.20 ve kernel 2.4.38 ile çalışan iki sistemde bazı kodlar var. kernel 2.4.38 altında Her ikisi de var gcc 3.2.2 ve glibc 2.3.2linux kernel'de pthread_create farkları 2.4.20 ve 2.4.36

, pthread_t kolları yeniden edilmiyor. Ağır yük testi altında, tutamaçlar 0xFFFFFFFF'a ulaştığında uygulama çöküyor.

:

Bu basit örnek sorunu yeniden

(BT parçacığı tarayıcıları ve bir ağ portu kullanan dağıtımlarda uygulama kilitleniyor soket bağlantılarını işlemek için oluşturulan çünkü ilk etapta bu şüpheli) 2.4.20 altında
void* ThreadProc(void* param) 
{ 
    usleep(10000); 
    printf(" Thread 0x%x\n", (unsigned int)pthread_self()); 
    usleep(10000); 
    return NULL; 
} 

int main(int argc, char* argv[]) 
{ 
    pthread_t sThread; 

    while(1) 
    { 
     pthread_create(&sThread, NULL, ThreadProc, NULL); 
     printf("Created 0x%x\n", (unsigned int)sThread); 
     pthread_join(sThread, NULL); 
    }; 

    return 0; 
} 

:

Created 0x40838cc0 
    Thread 0x40838cc0 
    Created 0x40838cc0 
    Thread 0x40838cc0 
    Created 0x40838cc0 
    Thread 0x40838cc0 
...and on and on... 

2.4.36 altında:

Created 0x4002 
    Thread 0x4002 
    Created 0x8002 
    Thread 0x8002 
    Created 0xc002 
    Thread 0xc002 
...keeps growing... 

kernel 2.4.36 geri dönüş tutamaçlarını nasıl alabilirim? Maalesef çekirdeği kolayca değiştiremiyorum. Teşekkürler!

+1

Geçmişe selamlar! Böyle bir çekirdek davranışta programınıza bağlı olarak iyi bir fikir olduğunu düşünmüyorum, programınızı düzeltmeniz gerekir. – PlasmaHH

+0

@PlasmaHH: Program gayet iyi; 'pthread_join' tüm iş parçacığı kaynaklarını serbest bırakmalıdır. Sorun şu ki, o çekirdek sürümde, görünüşe göre değil. –

+0

@MikeSeymour: Sence bunu ne düşünüyorsun? Bana göre, her defasında farklı bir tutamaç veriyormuş gibi gözüküyor, bir önceki tutamaç boşaldığında bile mükemmel bir şey. Aynen a = malloc (5) gibi, serbest (a) a = = malloc (5); doğru olmamalı. – PlasmaHH

cevap

4

Gözlemleriniz doğruysa, yalnızca iki olası çözüm var.

Ya

    çekirdeği yükseltme
  1. . Bu sizin için uygun olabilir veya olmayabilir.
  2. Uygulamanızdaki konuları geri dönüştürün.

Seçenek 2, çekirdek hatalı davranıyor olsa bile yapabileceğiniz bir şeydir. Kullanılmadığında uyku durumunda kalan bir iş parçacığı havuzunu tutabilirsiniz. İplik havuzları yaygın olarak bilinen bir yazılım mühendisliği kalıbıdır (bakınız http://en.wikipedia.org/wiki/Thread_pool_pattern). Bu muhtemelen sizin için daha iyi bir çözümdür.

+1

Her zaman '3 vardır. geri çekirdeği gelecekteki bir çekirdek sürümünden bir düzeltme ve kendi çekirdeğini yeniden oluştur –

+0

@Kevin A. Naudé: Evet, muhtemelen bir iş parçacığı havuzu uygulamak zorunda kalacağım. Hala birilerinin 2.4.36 çekirdeği için basit bir çözüm bulacağını umuyordum. Dediğim gibi, çekirdeği kolayca değiştiremiyorum. (Kendi başıma dahil etme dahil) – Scott

+0

@Scott: Sorunu gideren yamalı bir çekirdek bile oluşturamazsanız, çekirdeği düzeltme umudunuz yoktur. İş parçacığı havuzu, en iyi (belki de sadece) seçeneğiniz olabilir. –

0

Döndü Yüklerimde, iş parçacıklarıma düzgün bir şekilde katılmıyordum.

Yükleme sınamasını yeniden çalıştırdığımda, iş parçacığı tutamaçları 0xFFFFF002'ye ulaştı, ardından 0x1002'ye aktarıldı ve mutlu bir şekilde devam etti.

Hikayenin Ahlakı: Konularınızın birleştirildiğini veya koptuğundan emin olun!