Linux程式設計signal函式使用
題目:
編寫一段程式,使用系統呼叫fork( )建立兩個子程序,再用系統呼叫signal( )讓父程序捕捉鍵盤上來的中斷訊號(即按ctrl+c鍵),當捕捉到中斷訊號後,父程序用系統呼叫kill( )向兩個子程序發出訊號,子程序捕捉到訊號後,分別輸出下列資訊後終止:
Child process 1 is killed by parent!Child process 2 is killed by parent!
父程序等待兩個子程序終止後,輸出以下資訊後終止:
Parent process is killed!
原始程式:
#include <stdio.h> #include <signal.h> #include <unistd.h> void go(); void stop1(),stop2(); int p1,p2; main( ) { while((p1=fork( ) )==-1); /*建立子程序p1*/ if (p1>0) { while((p2=fork( ) )==-1); /*建立子程序p2*/ if(p2>0) { printf("This is parent %d.\n", getpid()); signal(SIGINT,go); /*接收到訊號,轉go*/ pause(); sleep(2); // wait for the operation of child wait(0); wait(0); printf("Parent process is killed!\n"); exit(0); } else if(p2 == 0) { printf("This is child_2 %d.\n", getpid()); signal(17,stop2); /*接收到軟中斷訊號17,轉stop2*/ pause(); } } else if(p1 == 0) { printf("This is child_1 %d.\n", getpid()); signal(16,stop1); /*接收到軟中斷訊號16,轉stop1*/ pause(); } } void go() { kill(p1,16); /*向p1發軟中斷訊號16*/ kill(p2,17); /*向p2發軟中斷訊號17*/ } void stop2() { printf("Child process 2 is killed by parent!\n"); exit(0); } void stop1() { printf("Child process 1 is killed by parent!\n"); exit(0); }
但是這段程式,並沒有按照預期的結果,輸出“Child process 1 is killed by parent”和"Child process 2 is killed by parent!"。
在輸入Ctrl+C後,父程序和子程序同時結束了,子程序並沒有處理為其設定的訊號,是什麼原因呢?
因為子程序從父程序中繼承了Ctrl+C訊號,及其預設的處理程式,在子程序中並沒有遮蔽Ctrl+C訊號,因此,當輸入Ctrl+C訊號時,子程序會在處理父程序為其指定的訊號之前,呼叫預設的處理Ctrl+C訊號的程式,直接退出。因此,解決這個問題的辦法,就是在子程序中遮蔽掉系統預設的對Ctrl+C訊號的處理,如下:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
void go();
void stop1(),stop2();
pid_t p1,p2;
void main( )
{
int status = -1;
int rtv;
while((p1=fork( ) )==-1); /*建立子程序p1*/
if (p1>0)
{
while((p2=fork( ) )==-1); /*建立子程序p2*/
if(p2>0)
{
printf("Parent process %d\n", getpid());
signal(SIGINT,go); /*接收到訊號,轉go*/
pause();
sleep(2);
wait(NULL);
wait(NULL);
printf("Parent process is killed!\n");
exit(0);
}
else
{
printf("Process 2, pid %d\n", getpid());
signal(SIGINT, SIG_IGN);//遮蔽預設的 SIGINT訊號處理
signal(SIGUSR2, stop2);
if(signal(SIGUSR2,stop2) == SIG_ERR) {
printf("Can't catch SIGUR2");
}
pause();
printf("Process 2 End\n");
}
}
else
{
printf("Process 1, pid %d\n", getpid());
signal(SIGINT, SIG_IGN);//遮蔽預設的 SIGINT訊號處理 if(signal(SIGUSR1,stop1) == SIG_ERR) {
printf("Can't catch SIGUR2");
}
pause();
printf("Process 1 End\n");
}
printf("child exit status is %d\n", WEXITSTATUS(status));
}
void go()
{
int rtv;
printf("Func go\n");
rtv = kill(p1,SIGUSR1); /*向p1發軟中斷訊號16*/
if(rtv) {
printf("fail to send signal 16 to p1\n");
} else {
printf("Succed in sending signal 16 to p1\n");
}
rtv = kill(p2,SIGUSR2); /*向p2發軟中斷訊號17*/
if(rtv) {
printf("fail to send signal 17 to p2\n");
} else {
printf("Succed in sending signal 17 to p2\n");
}
}
void stop2()
{
printf("Child process 2 is killed by parent!\n");
exit(0);
}
void stop1()
{
printf("Child process 1 is killed by parent!\n");
exit(0);
}
參考:UNIX環境高階程式設計_第二版中文
相關推薦
Linux程式設計signal函式使用
題目: 編寫一段程式,使用系統呼叫fork( )建立兩個子程序,再用系統呼叫signal( )讓父程序捕捉鍵盤上來的中斷訊號(即按ctrl+c鍵),當捕捉到中斷訊號後,父程序用系統呼叫kill( )向兩個子程序發出訊號,子程序捕捉到訊號後,分別輸出下列資訊後終止:
linux系統程式設計-exec函式族
exec函式族 fork建立子程序後執行的是和父程序相同的程式(但有可能執行不同的程式碼分支),子程序往往要呼叫一種exec函式以執行另一個程式。 當程序呼叫一種exec函式時,該程序的使用者空間程式碼和資料完全被新程式替換,從新程式的啟動例程開始執行。 呼叫
Linux初級運維(十五)——bash指令碼程式設計之函式
一、函式 函式:功能,function 程式碼重用的功能。 結構化程式設計,不能獨立執行,需要呼叫
Linux程式設計之ioremap函式的例項解析
void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) 入口: phys_addr:要對映的起始的IO地址; size:要對映的空間的大小; flags:要對映
三十、Linux 程序與訊號——訊號的概念及 signal 函式
30.1 訊號的基本概念 訊號(signal)機制是Linux 系統中最為古老的程序之間的通訊機制,解決程序在正常執行過程中被中斷的問題,導致程序的處理流程會發生變化 訊號是軟體中斷 訊號是非同步事件 不可預見 訊號有自己的名稱和編號 訊號和異常處理機制
linux下的OPENSSL程式設計- 簡單函式介紹
在利用OpenSSL開始SSL會話之前,需要為客戶端和伺服器制定本次會話採用的協議,目前能夠使用的協議包括TLSv1.0、SSLv2、SSLv3、SSLv2/v3。需要注意的是,客戶端和伺服器必須使用相互相容的協議,否則SSL會話將無法正常進行。(3 ) 建立會話環境在OpenSSL中建立的SSL會話環境稱為
Linux中網路程式設計常用函式
1.位元組序轉換 CPU 向記憶體儲存資料以及解析資料的方式有兩種: 1)大端位元組序(Big Endian): 高位位元組存放在低位地址上 2) 小端位元組序(Little Endian): 高位位元組存放在高位地址上 因為這種差異性,異導致資料解析的混亂
Linux 檔案程式設計—fopen函式
1.2 檔案的輸入輸出函式 鍵盤、顯示器、印表機、磁碟驅動器等邏輯裝置, 其輸入輸出都可以通過檔案管理的方法來完成。而在程式設計時使用最多的要算是磁碟檔案, 因此本節主要以磁碟檔案為主, 詳細介紹Turbo C2.0提供的檔案操作函式, 當然這些對檔案的操作函式也
Linux C程式設計一些函式彙總
之前專案用到的函式彙總一下: 1.access 原型:int access(const char *filenpath, int mode); 標頭檔案:io.h 功 能: 確定檔案或資料夾的訪問許可權。檢查某個檔案的存取方式,比如說是隻讀方式、只寫方
Linux訊號signal介紹,signal()函式,sigaction()函式
訊號(signal)是一種程序間通訊機制,它給應用程式提供一種非同步的軟體中斷,使應用程式有機會接受其他程式活終端傳送的命令(即訊號)。應用程式收到訊號後,有三種處理方式:忽略,預設,或捕捉。程序收到一個訊號後,會檢查對該訊號的處理機制。如果是SIG_IGN,就忽略該訊號;如果是SIG_DFT,則會採
linux signal 函式對中斷的應用
在https://blog.csdn.net/engineer_james/article/details/83867466 寫一個android程序後臺的過程 但是我們用CPP C 開發避免不了 分配記憶體或者 指標,如果在linux 程序跑的時候,出現死了或
linux基礎(二十)----linux程式設計基礎----子程式----函式
寫一個又大又複雜的程式的技巧之一,就是將該程式分解成一些稱之為子程式的小程式,而在每一個子程式中,又可以把重複出現的程式碼組織到一起形成一個函式。 函式和子程式執行的是主程式某一特定的任務。我們要做的工作就是寫一個主程式,當需要某一個函式和子程式的時候就
函式指標&回撥函式&linux中的signal函式
1. int (*func)();函式指標,指向的函式為空引數,返回整型; 2. 回撥函式是一個程式設計師不能顯式呼叫的函式;通過將回調函式的地址傳給被呼叫者從而實現呼叫。 回撥函式是一個通過函式指標呼叫的函式。如果你把函式的指標(地址)作為引數傳遞給另一個函式,當這個指標
linux之基礎shell指令碼程式設計3 函式陣列
本章主要寫shell有關函式陣列使用 七 函式 7.1 函式的介紹 函式function是由若干條shell命令組成的語句塊,實現程式碼重用和模組化程式設計。 它與shell程式形式上是相似的,不同的是它不是一個單獨的 程序,不能獨立執行,而是shel
linux C程式設計--popen函式詳解
#include <stdio.h> FILE *popen(const char *command, const char *type); int pclose(FILE *stream); 描述 popen() 函式 用 建立管道 的 方式 啟動一個 程序, 並呼叫 shell. 因為 管道
Linux shell指令碼程式設計之函式
在編寫功能比較複雜的shell指令碼時,完成具體任務的程式碼有時會被重複使用,bash shell指令碼提供函式特性實現程式碼複用,函式是被賦予名稱的指令碼程式碼塊。 一、建立函式 在bash shell指令碼中建立函式的格式如下: function name() {
linux signal函式使用
#define SIG_IGN (void (*)())1 alarm(設定訊號傳送鬧鐘) 相關函式 signal,sleep 表頭檔案 #include 定義函式 unsigned int alarm(unsigned int seconds); 函式說明 alarm()用來設定訊號SIGALRM在經過引
linux下串列埠程式設計設定函式---------set_opt(fd1,115200,8,'N'1)--------------------
open /dev/ttys0, 裝置檔案之後,得到檔案描述符, 對串列埠進行設定。 /** *串列埠設定函式:例(fd1, 115200, 8, 'N', 1); *引數: *fd:串列埠裝置節點
【Linux程式設計】程序終止和exit函式
執行由atexit函式登記的各終止處理程式總是執行一個標準IO庫的清理關閉操作:為所有開啟流呼叫fclose函式呼叫_exit或_Exit函式返回核心注意最後一步,exit最終還是要呼叫_exit或_Exit回到核心。程序有5種正常終止方式和3種異常終止方式(P178),不管程序如何終止,最後都會執行核心中
C/C++程式設計教訓----函式內靜態類物件初始化非執行緒安全(C++11之前)
不少程式設計師在編寫程式的時候,會使用函式內靜態(static)變數,既能滿足函式內這個變數可以持久的記錄某些資訊,又使其訪問範圍的控制侷限於函式內。但函式內靜態類物件初始化是非執行緒安全的。 問題背景 在我們產品中對log4cxx做了一些簡單的封裝 (採用VS2005編譯),其中會