1. 程式人生 > >Linux程式設計signal函式使用

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編譯),其中會