Bu yazıda size C dilini kullanarak Linux’ta sinyal işleyicileri nasıl kullanacağınızı göstereceğiz, ancak önce bir sinyalin ne olduğunu, kullanabileceğiniz bazı ortak sinyalleri nasıl üreteceğini tartışacağız. Programınız Ardından, program çalışırken program tarafından çeşitli sinyallerin nasıl işlendiğine bakacağız. Uygulamak. Başlayalım.
sinyal
Semafor, önemli bir olayın geldiğini bir işleme veya iş parçacığına bildirmek için oluşturulan bir olaydır. Bir işlem veya iş parçacığı bir sinyal aldığında, işlem veya iş parçacığı yapmakta olduğu şeyi durduracak ve bazı eylemler gerçekleştirecektir. Sinyaller süreçler arasındaki iletişim için faydalı olabilir.
standart sinyaller
Bayraklar başlık dosyasında belirtilir referans h Bir makro sabiti olarak Signal adı “SIG” ile başlar ve ardından sinyalin kısa bir açıklaması gelir. Bu nedenle, her sinyalin benzersiz bir sayısal değeri vardır. Programınız her zaman semafor adını kullanmalıdır, semafor numarasını değil. Bunun nedeni, sinyal numarasının sisteme bağlı olarak değişebilmesi ancak isimlerin anlamının standart olmasıdır.
kesin NSIG seçilen sinyallerin toplam sayısıdır. değer NSIG Seçilen toplam sinyal sayısından bir fazla (tüm sinyal numaraları sırayla atanır).
Standart sinyaller şunlardır:
gösterici isim | Tanılama |
Öyleyse iç çek | Süreci askıya alın. SIGHUP sinyali, muhtemelen uzak bağlantının kesilmesi veya kapatılması nedeniyle kullanıcı ucunun bağlantısının kesildiğini belirtmek için kullanılır. |
sinyal | süreci kesintiye uğratır. SIGINT sinyali, kullanıcı bir INTR karakteri (genellikle Ctrl + C) yazdığında gönderilir. |
Takip et | Anlaşmadan çekil. Kullanıcı bir QUIT karakteri (genellikle Ctrl + \) yazdığında, bir SIGQUIT sinyali gönderilir. |
Siegel | yasa dışı talimatlar Yanlış veya ayrıcalıklı bir talimatı yürütmeye çalışıldığında bir SIGILL sinyali üretilir. Ayrıca, yığın taştığında veya sistem bir sinyal işleyiciyi çalıştırırken sorun yaşadığında bir SIGILL üretilebilir. |
SIG TUZAĞI | Tuzak izleme. Bir kesme noktası talimatı ve başka bir tuzak talimatı bir SIGTRAP sinyali üretecektir. Hata ayıklayıcı bu sinyali kullanır. |
SİGABRT | ortadan kaldırır. Abort() işlevi çağrıldığında SIGABRT sinyali üretilir. Bu sinyal, programın kendisi tarafından algılanan ve abort() işlev çağrısı tarafından bildirilen bir hatayı belirtir. |
kuruyacak | Kayan nokta istisnası. Büyük bir hesaplama hatası oluştuğunda bir SIGFPE sinyali üretilir. |
SIGUSR1 ve SIGUSR2 | SIGUSR1 ve SIGUSR2 sinyalleri dilediğiniz gibi kullanılabilir. Süreçler arasında basit bir iletişim için, sinyali alan programda onlar için bir sinyal işleyici yazmakta fayda var. |
Sinyaller için varsayılan eylem
Her sinyalin aşağıdakilerin bir varsayılan eylemi vardır:
şart: İşlem sonlandırılacaktır.
çekirdek: İşlem bitecek ve bir çekirdek dökümü dosyası üretecek.
Ateş: İşlem sinyali yok sayacaktır.
Durmak: İşlem duracaktır.
Tamamlamak: Süreç durmadan devam edecek.
Varsayılan eylem, sihirbaz işlevi kullanılarak değiştirilebilir. Bazı sinyallerin varsayılan eylemi değiştirilemez. sekel E SİGABRT Bahsetmek için varsayılan eylem değiştirilemez veya göz ardı edilemez.
sinyal işleme
İşlem bir sinyal alırsa, işlemin bu tür sinyal için bir işlem seçeneği vardır. Süreç, sinyali yok sayabilir, bir işleyici işlevi tanımlayabilir veya böyle bir sinyal için varsayılan eylemi kabul edebilir.
- Semafor için belirtilen eylem yoksayılırsa, semafor hemen atılır.
- Program, aşağıdaki gibi bir işlevi kullanarak bir işleyici işini kaydedebilir: sinyal veya İmza. Sinyali yakalayan bir işlemci denir.
- Sinyal işlenmez veya atılmazsa, varsayılan eylemi gerçekleşir.
kullanarak sinyali işleyebiliriz. sinyal veya İmza İşlev. Burada ne kadar basit olduğunu görüyoruz Sinyal() Fonksiyon, sinyal işleme için kullanılır.
int sinyal ()(int sinyalVeGeçersiz(*İşlev)(int))
NS Sinyal() Arayacağım İşlev İşlem bir sinyal alırsa çalışır sinyal. NS Sinyal() İşleve bir işaretçi döndürür İşlev Başarılı olursa false’u errno’ya, aksi takdirde false’u -1’e döndürür.
NS İşlev Bir göstergenin üç değeri olabilir:
- SIG_DFL: Varsayılan sistem işlevine bir işaretçi SIG_DFL()ilan edildi h Ana dosya. Bir semaforun varsayılan eylemini elde etmek için kullanılır.
- SIG_IGN: sistem yoksayma işlevine işaretçi. SIG_IGN()ilan edildi h Ana dosya.
- Kullanıcı tanımlı işleyici işlevi işaretçisi: Kullanıcı tanımlı işleyici iş türü uzay(int)
dönüş türünün geçersiz olduğu ve int türünde bir bağımsız değişkene sahip olduğu anlamına gelir.
Temel bir sinyal işlemci örneği
#birleştirmek için
#birleştirmek için
#birleştirmek için GeçersizTüccar söyle( intsinyal)
{
// İşleyici işlevinin dönüş türü geçersiz olmalıdırBaskı(“\ndahili işlemci işlevi\n“)
;
} into()
{sinyal(sinyalVeTüccar söyle);
// Sinyal işleyiciyi kaydetiçin( intKahve=1;;Kahve++){
// bitmemiş döngüBaskı(%d: ana işlevin içinde\n“VeKahve)
;uyumak(1);
// bir saniye geciktir
}dönüş0
;
}
Example1.c çıktı ekran görüntüsünde, ana işlevde sonsuz döngünün yürütüldüğünü görebiliriz. Kullanıcı Ctrl+C yazdığında, ana işlev çalışmayı durdurur ve sinyal işleyici işlevi çağrılır. İşlemci işi tamamlandıktan sonra ana işlev yürütülmeye devam eder. Kullanıcı Ctrl + \ yazdığında işlem sonlandırılır.
Sinyalleri yoksayma örneği
#birleştirmek için
#birleştirmek için
#birleştirmek için into()
{sinyal(sinyalVeSIG_IGN);
// Sinyali yoksaymak için sinyal işleyiciyi kaydediniçin( intKahve=1;;Kahve++){
// bitmemiş döngüBaskı(%d: ana işlevin içinde\n“VeKahve)
;uyumak(1);
// bir saniye geciktir
}dönüş0
;
} Burada işlemci işlevi kayıtlıdır SIG_IGN() Sinyal eylemini yoksayma işlevi. Yani, kullanıcı Ctrl + C yazdığında, sinyal
Sinyal üretilir, ancak eylem göz ardı edilir.
Sinyal işleyici örneğinin yeniden kaydedilmesi
#birleştirmek için
#birleştirmek için
#birleştirmek için GeçersizTüccar söyle( intsinyal)
{Baskı(“\ndahili işlemci işlevi\n“)
;sinyal(sinyalVeSIG_DFL);
// Varsayılan eylem için sinyal işleyiciyi yeniden kaydedin
} into()
{sinyal(sinyalVeTüccar söyle);
// Sinyal işleyiciyi kaydetiçin( intKahve=1;;Kahve++){
// bitmemiş döngüBaskı(%d: ana işlevin içinde\n“VeKahve)
;uyumak(1);
// bir saniye geciktir
}dönüş0
;
} Example3.c çıktı ekran görüntüsünde, kullanıcı Ctrl+C’yi ilk kez yazdığında işleyici işlevinin çağrıldığını görebiliriz. İşleyici işlevinde, sinyal işleyici yeniden yüklenir. SIG_DFL Varsayılan referans çalışması için. Kullanıcı Ctrl+C’yi ikinci kez yazdığında, varsayılan eylem olan işlem sonlandırılır. sinyal
Sinyal.
Sinyali gönder:
Bir süreç ayrıca açıkça kendisine veya başka bir sürece atıfta bulunabilir. Raise() ve kill() işlevleri, sinyal göndermek için kullanılabilir. Her iki işlev de Signal.h başlık dosyasında bildirilir.intyüklemek( intsinyal
) Boost() işlevi, sinyal göndermek için kullanılır sinyal
çağrı süreci için (kendisine). Başarılı olursa sıfır, başarısız olursa sıfır olmayan bir değer döndürür. intöldürme(pid_t pidVe intsinyal
) Kill fonksiyonu bir sinyal göndermek için kullanılır. sinyal tarafından belirtilen bir işlem veya işlemler kümesipid
.
SIGUSR1 sinyal işlemcisine bir örnek
#birleştirmek için
#birleştirmek için GeçersizTüccar söyle( intsinyal)
{Baskı(dahili işlemci işlevi\n“)
;
} into()
{sinyal(köprü olacak 1VeTüccar söyle);
// Sinyal işleyiciyi kaydetBaskı(ana işlev içinde\n“)
;yüklemek(köprü olacak 1)
;Baskı(ana işlev içinde\n“)
;dönüş0
;
}
Burada süreç, Upgrade() işlevini kullanarak kendisine bir SIGUSR1 sinyali gönderir.
Kill Sample Programı ile yükseltin
#birleştirmek için
#birleştirmek için
#birleştirmek için GeçersizTüccar söyle( intsinyal)
{Baskı(dahili işlemci işlevi\n“)
;
} into()
{pid_t pid
;sinyal(köprü olacak 1VeTüccar söyle);
// Sinyal işleyiciyi kaydetBaskı(ana işlev içinde\n“)
;pid=abartılı();
// işlem kimliğiöldürme(pidVeköprü olacak 1);
// SIGUSR1’i kendisine gönderBaskı(ana işlev içinde\n“)
;dönüş0
;
} Burada, işlemi gönderin köprü olacak 1 kullanarak kendinize bakın öldürme() İşlev. getpid()
İşlem kimliğinin kendisini almak için kullanılır. Aşağıdaki örnekte, ebeveyn ve alt süreçlerin nasıl iletişim kurduğunu (süreçler arası iletişim) göreceğiz. öldürme()
ve sinyal fonksiyonu.
İpuçları ile ebeveyn-çocuk iletişimi
#birleştirmek için
#birleştirmek için
#birleştirmek için
#birleştirmek için Geçersizsig_handler_parent( intsinyal)
{Baskı( Ebeveyn: Çocuktan bir yanıt sinyali aldı\n“)
;
} Geçersizsig_handler_child( intsinyal)
{Baskı( Çocuk: Bir ebeveynden bir sinyal aldı\n“)
;uyumak(1)
;öldürme(saçmalık()Veköprü olacak 1)
;
} into()
{pid_t pid
;eğer((pid=çatal())<0)
{Baskı(“Çatal başarısız oldu\n“)
;çıkış(1)
;
}
/* alt süreç */diğereğer(pid==0)
{sinyal(köprü olacak 1Vesig_handler_child);
// Sinyal işleyiciyi kaydetBaskı(Çocuk: Sinyali bekleyin\n“)
;Durmak()
;
}
/* üst işlemler */diğer
{sinyal(köprü olacak 1Vesig_handler_parent);
// Sinyal işleyiciyi kaydetuyumak(1)
;Baskı(Ebeveyn: Çocuğa sinyal gönder\n“)
;öldürme(pidVeköprü olacak 1)
;Baskı(Ebeveyn: Cevap bekliyorum\n“)
;Durmak()
;
}dönüş0
;
} Burada, çatal() İşlev bir alt süreç oluşturur ve alt sürece sıfır ve ana sürece alt süreç kimliğini döndürür. Böylece PIN, ebeveyn-çocuk sürecini tanımlamak için tarandı. Ebeveyn süreçte, çocuk sürecin kendi sinyal işleyici işlevini kaydedebilmesi ve ebeveynden sinyal bekleyebilmesi için 1 saniye uyur. 1 saniye sonra ana eylemi gönder köprü olacak 1 Çocuk sürecine sinyal verin ve çocuktan yanıt sinyali bekleyin. Çocuk süreçte, önce ebeveynin sinyali beklenir ve sinyal alındığında işleyici işlevi çağrılır. İşleyici işinden, alt süreç başka bir süreç gönderir. köprü olacak 1 Ebeveynlere bir referans. Burada getppid()
İşlev, üst işlem kimliğini almak için kullanılır.
çözüm
Linux’ta işaretleme büyük bir sorundur. Bu yazımızda en basitinden sinyal işlemeyi gördük ve ayrıca sinyal işlemeyi öğrendik. İletişim, bir sürecin kendisine ve diğer süreçlere nasıl sinyal gönderebileceği ve süreçler arasında sinyalleşmenin nasıl kullanılacağı.
Diğer gönderilerimize göz at
[wpcin-random-posts]
İlk Yorumu Siz Yapın