1. 程式人生 > >詳解linux進程間通信-信號

詳解linux進程間通信-信號

前言 prime 退出 pause 其余 type 客戶端 arm 進程間通信

  前言:之前說看《C++ Primer 》暫時擱淺一下,迷上公司大神寫的代碼,想要明白,主要是socket、進程間通信!

  知道進程間通信:信號、信號量、管道、消息隊列、共享內存(共享存儲),也能寫些簡單代碼進行通信,但不知道應用在哪?感覺很多小夥伴跟我有類似經歷吧?

  一、應用實例:

  要去linux設備上去添加、改密用戶:本地去linux設備添加用戶,用socket實現,其實大神改的ssh源碼來實現的,這不是我要講的重點,而我要講的是準備過程,去登陸linux設備,要準備好:管理員、密碼等。

  簡略說明中間過程:頁面點擊添加,調用cli(socket的客戶端,socket本地通信),server.c(socket服務端)裏fork子進程,而實現登錄linux設備的是ssh進程,但是ssh進程需要管理員、密碼等信息,那子進程怎麽傳給它,就需要進程間通信方式了,大神用的是消息隊列。

  講到這裏不知道明白了麽?有問題可以隨時留言。

  接下來將詳解進程間通信方式。

  二、進程間通信-信號:

  1、信號概念:

  信號的概念
  首先,每個信號都有一個名字。這些名字都以三個字符 S I G開頭。 S I G A L R M是鬧鐘信號,當由a l a r m函數設置的時
間已經超過後產生此信號。

  產生信號條件:

  ? 當用戶按某些終端鍵時,產生信號。
  ? 硬件異常產生信號:除數為0、無效的存儲訪問等等。
  ? 進程用k i l l 函數可將信號發送給另一個進程或進程組。
  ? 用戶可用k i l l 命令將信號發送給其他進程。此程序是 k i l l函數的界面。
  ? 當檢測到某種軟件條件已經發生,並將其通知有關進程時也產生信號。

  可以要求系統在某個信號出現時按照下列三種方式中的一種進行操作:
  (1) 忽略此信號。
  (2) 捕捉信號。
  (3) 執行系統默認動作。
  2、signal函數

  signal(int signum, sighandler_t handler);

  格式 :signal(信號,信號處理函數)
  功能 :登記信號 當信號到來時 執行信號處理函數 而不采用默認的處理方式

  註:sighandler_t是函數指針,typedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);

  程序:檢測信號,調用處理函數 

#include "my.h"

void sig_fun(int sig)
{
puts("ding-ling!");
}

int main()
{
signal(SIGALRM,sig_fun);
alarm(5);
for(;;) {} 
return 0;

}

---程序2.2---

註:

  5秒之後產生產生SIGALRM信號,調用sig_fun函數。

  alarm函數:

  使用a l a r m函數可以設置一個時間值 (鬧鐘時間),在將來的某個時刻該時間值會被超過。當
所設置的時間值被超過後,產生 S I G A L R M信號。

  #include <unistd.h>
  unsigned int alarm(unsigned int s e c o n ds) ;
  

  註:“my.h”是我自定義頭文件,因為頭文件方便書寫,為了便於調試和理解,把頭文件粘出來,如下: 

#ifndef MY_H_
#define MY_H_

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <pthread.h>
#include <semaphore.h>
#endif

  3、其他常用函數

  (1)killr a i s e函數
  k i l l函數將信號發送給進程或進程組。 r a i s e函數則允許進程向自身發送信號。  
  

  #include <sys/types.h>  

  #include <signal.h>

  int kill(pid_t p id, int s i g no) ;
  int raise(int s i g n o) ;
  兩個函數返回:若成功則為 0,若出錯則為-1

  (2)pause函數
  p a u s e函數使調用進程掛起直至捕捉到一個信號。
  #include <unistd.h>
  int pause(void);

  程序:優化“程序2.2”,用pause函數代替死循環,檢測信號之後並退出,如下:

#include "my.h"

void sig_fun(int sig)
{
puts("ding-ling!");
}

int main()
{
signal(SIGALRM,sig_fun);
alarm(5);
printf("111\n");
pause();
//for(;;) {} 
printf("222\n");
return 0;

}

---程序2.3---

總結:以上介紹進程間通信應用實例,然後介紹了進程間通信的信號,接下來會介紹其余進程間通信方式。

  

  

  

  

  

詳解linux進程間通信-信號