bekleyin bash-builtin yüzde 100 bir CPU yakar


16

En azından GNU bash sürüm 4.3.42 x86_64 && GNU bash sürüm 4.3.11 x86_64 üzerinde oluşur

Ben bir sinyal ( SIGUSR1 olarak ) tarafından bir kesinti almak için sleep & wait $!basit yerine kullanın . Ama öyle görünüyor ki, bash-builtin, aşağıdakileri çalıştırdığınızda garip bir şekilde davranıyor.sleepsleepwait

Terminal 1:

cat <(
   trap 'echo SIGUSR1' SIGUSR1;
   echo $BASHPID;
   while :;do
       sleep 1 &
       wait $!;
       echo test;
   done
   )&

Terminal 2:

kill -10 /the pid of the subshell, printed by the previous command/

Terminal 1:

^C (ctrl + C)

Sonra, bir CPU'yu yüzde 100 oranında yakan alt kabuğu alıyorum.

Terminal 1:

pkill -P $(pgrep -P $$)

Bu davranışın neden oluştuğu hakkında bir fikriniz var mı?

Not : cat <(/subshell/)Arka planda değilken sorun oluşmaz .


Bu davranışı deneyimlemenin başka bir yolu

Terminal 1:

(
   trap 'echo SIGUSR1' SIGUSR1;
   echo $BASHPID;
   while :;do
       sleep 1 &
       wait $!;
       echo test;
   done
)&

Terminal 2:

kill -10 /the pid of the subshell, printed by the previous command/

Terminal 1:

fg
^C (ctrl + C)

Sonra donmuş bir kabuk alın.


Bu davranışı deneyimlemenin üçüncü yolu

Terminal 1:

(
   trap 'echo SIGUSR1' SIGUSR1;
   echo $BASHPID;
   while :;do
       sleep 1 &
       wait $!;
       echo test;
   done
)

Terminal 2:

kill -10 /the pid of the subshell, printed by the previous command/

Terminal 1:

^C (ctrl + C)

Sonra donmuş bir kabuk alın.


Bunu hata ayıklamak için, muhtemelen Bash'ı kaynaklardan oluşturmalı ve nerede döngü yaptığını (bir hata ayıklayıcıyla kesmeli veya yazdırma ifadeleri ekliyorsunuz) ve neden döngü yaptığını öğrenmelisiniz.
Kaz

1
Garip? Burada çoğaltamam, bash 4.3.42 (1) -release (x86_64-pc-linux-gnu) kullanıyorum. Debian 8. Çekirdek 4.6.1-1. Söylediğin tüm testleri yapıyorum ama CPU hala normal çalışıyor ... Tam olarak fg ve sonra CTRL + C gibi söylediklerini yapıyorum.
Luciano Andress Martini

bash4.4'te yerleşik ve sinyallerle ilgili bazı şeylerin değiştiğini okuduğumu hatırlıyorum , belki de burada etkilenebilir.
phk

Bash 4.4.20wait , buna çok benzeyen bir spinloop sorununu giderir . Sonsuza kadar alt süreçleri ortaya çıkaran bir döngüde bana çarptı. Ancak, senaryoyu 4.4.20'de test ettim ve bu hala bir problemdi. İlginç bir şekilde, oluşturduğum bir sürüme bir hata ayıklayıcı eklediğimde, bunun etrafında döngü olduğunu görebiliyordum, ancak bunun da kırılma etkisi vardı ve döngü tekrar 'test' çıktısı vermeye başlayacaktı. Başka bir deyişle: hata ayıklayıcıyı bağlamak eğrilmeyi durdurdu.
Halfgaar

Yanıtlar:


1

Gözlemler

  • ctrl+cSIGINTTerminal 1'deki fg sürecine gönderir
  • dolayısıyla, kill -2 <PID>Terminal 2'de yürütmek ctrl+cTerminal 1'de vurmakla aynıdır
  • Terminal 2 tutamaçlarını doğru şekilde çalıştırmadan önce yukarıdaki iki noktadan birini yapmakkill -10 <PID>SIGINT
  • Terminal 2'de (sinyal gönderme ) yürütüldükten sonra bunu yapmak doğru işlemez ve sorunlu davranışa yol açarkill -10 <PID>SIGUSR1SIGINT
  • Değiştirme kill -2 <PID>Terminal 2 (in SIGINT) ile kill -15 <PID>( SIGTERM) ya da kill -9 <PID>( SIGKILLdoğru sinyal işleme için her zaman) yol açar.
  • kill -10 <PID>Terminal 2'de yürütmek waityerleşik testparçayı kesintiye uğratır, ancak sinyal SIGUSR1yakalandıktan ve döngü devam ettikten hemen sonra yazdırıldığı için döngüyü terk etmez .
  • Gönderme SIGINT, yürütme döngüsünden kopar ve kabuğu dondurur veya asla kesilmez waitve beklemede / donmaz.

Sonuç

SIGINTdoğru şekilde ele alınmaz ve kullanılmaz veya manuel olarak yakalandıktan sonra SIGUSR1veya kullanıcı tarafından tanımlanan başka bir yakalamadan sonra yok sayılır . Bu, işlemin hala var olduğu ve bu yüzden CPU'yu yediği / ısındığı veya kabuğu dondurduğu anlamına gelir. Yürütme kill -15 <PID>veya kill -9 <PID>Terminali 2 sona erdiği gelen / işlemini öldürür ve Terminal 1 üzerinde kontrol ve geri CPU rahatlatır verir.

Neden bu problem ortaya çıkıyor, hala bir sır olarak kalıyor, ama umarım birisi perdelerin arkasında gerçekten neler olduğunu açıklayabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.