-
- 一信号的處理
- 1 發送信号的系統函數
- 1raise
- sleep
- usleep
- pause
- 2alarm
- 1raise
- 2 信号集的基本概念和基本操作
- 1基本概念
- 2基本操作
- sigemptyset - 清空信号集
- sigfillset - 填滿信号集
- sigaddset - 添加信号到信号集中
- sigdelset - 删除信号集中的信号
- sigismember - 判斷信号是否存在
- 3 信号的屏蔽
- 1sigprocmask
- 2sigpending
- 4 計時器
- 5 擴充
- 1sigaction
- 2sigqueue
- 1 發送信号的系統函數
- 二程序間的通信技術
- 1 基本概念
- 2 通信方式
- 一信号的處理
一、信号的處理
1.1 發送信号的系統函數
(1)raise()
#include <signal.h>
int raise(int sig);
- 功能:
- 主要用于給目前正在調用的線程/線程發送參數指定的信号,對于單線程的程式來說,等價于
kill(getpid(), sig);
傳回值: - success —- 0,error —- 非0;
sleep()
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
- 功能:
- 主要用于使得目前正在調用的線程進入睡眠狀态,直到參數指定的秒數睡夠了,或者一個不能被忽略的信号到達了; 傳回值:
- 如果參數指定的秒數過去了,則傳回0,否則傳回還沒有來得及睡的秒數,也就是剩餘的秒數;
usleep()
#include <unistd.h>
int usleep(useconds_t usec); //useconds = unsigned int;
- 功能:
- 主要用于使得目前正在調用的線程睡眠參數指定的微秒;
pause()
#include <unistd.h>
int pause(void);
- 功能:
- 主要用于是的目前正在調用的程序或線程暫停程式的執行,等待信号的到來; 傳回值:
- 隻有當信号被捕獲時傳回-1,并設定errno為EINTR;
(2)alarm()
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
功能:
主要用于在進過參數指定的秒數之後,給目前正在調用的程序發送SIGALRM信号;
每次重新設定鬧鐘之後都會取消之前的鬧鐘,當參數為0時,專門用于取消鬧鐘;
傳回值:
如果之前沒有鬧鐘則傳回0,否則傳回之前鬧鐘剩餘的秒數;
1.2 信号集的基本概念和基本操作
(1)基本概念
信号集本質上就是若幹個信号組成的集合。
思考:
請問采用最節省記憶體空間的方式設計信号集的資料類型,如何設計?
分析:
int arr[64]; => 4*64 = 256B
short arr[64]; => 2*64 = 128B
char arr[64]; => 1*64 = 64B
采用每一個二進制位來代表一個信号,使用1表示有該信号,使用0表示沒有該信号;=> 8B
… 0010 0011 => 存在信号1、信号2、信号6
結論:
作業系統内部使用資料類型:
sigset_t
表示信号集的資料類型,該資料類型的大小是:128B;
typedef struct
{
unsigned long int __val[( / ( * sizeof (unsigned long int)))];
} __sigset_t;
typedef __sigset_t sigset_t
(2)基本操作
sigemptyset() - 清空信号集
#include <signal.h>
int sigemptyset(sigset_t *set);
sigfillset() - 填滿信号集
#include <signal.h>
int sigfillset(sigset_t *set);
sigaddset() - 添加信号到信号集中
#include <signal.h>
int sigaddset(sigset_t *set, int signum);
sigdelset() - 删除信号集中的信号
#include <signal.h>
int sigdelset(sigset_t *set, int signum);
sigismember() - 判斷信号是否存在
#include <signal.h>
int sigismember(const sigset_t *set, int signum);
傳回值:
信号存在傳回1,信号不存在傳回0,出錯傳回-1;
1.3 信号的屏蔽
在某些特殊程式的執行過程中,可能不允許被信号打斷,此時就需要使用信号的屏蔽技術來解決該問題;
(1)sigprocmask()
#include <signal.h>
/* Prototype for the glibc wrapper function */
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
- 功能:
- 主要用于檢查 / 修改即将屏蔽的信号集; 參數:
-
第一個參數:具體的屏蔽方式;
SIG_BLOCK - 使用目前屏蔽集 + 參數set屏蔽集
- ABC + CDE(set) =>ABCDE
SIG_UNBLOCK - 使用目前屏蔽集 - 參數set屏蔽集
- ABC - CDE(set) => AB
SIG_SETMASK - 使用參數set屏蔽集替換目前屏蔽集
- ABC CDE(set) => CDE
第二個參數:信号集類型的指針,用于指定新的信号集;
第三個參數:信号集類型的指針,用于帶出之前屏蔽的信号集;
如果不想帶出之前的屏蔽集,該參數給NULL即可;
注意:
信号的屏蔽并不是删除信号,而是相當于用一個隔闆把信号檔起來,對于可靠信号來說,産生了多少次,則在隔闆的另一側會排隊等待多少個,而對于不可靠信号來說,無論産生了多少次,在隔闆的另一側隻有一個信号排隊等待,當信号的屏蔽解除時,相當于将隔闆移開,隻要程序不結束,則全部依次處理;
(2)sigpending()
#include <signal.h>
int sigpending(sigset_t *set);
- 功能:
- 主要用于擷取信号屏蔽期間來過但沒來得及處理的信号集,通過參數set傳回;
1.4 計時器
在linux系統中,作業系統會為每一個程序管理3種計時器,分别為:真實計時器、虛拟計時器以及實用計時器,一般都使用真實計時器進行計時;
#include <sys/time.h>
int getitimer(int which, struct itimerval *curr_value);
int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
- 功能:
- 主要用于擷取 / 設定計時器的參數資訊; 參數:
-
第一個參數:計時器的類型;
ITIMER_REAL - 真實計時器,産生SIGALRM信号
- 統計程序消耗的真實時間
ITIMER_VIRTUAL - 虛拟計時器,産生SIGVTALRM信号
- 統計程序在使用者态下消耗的時間(了解)
ITIMER_PROF - 實用計時器,産生SIGPROF信号
- 統計程序在使用者态和核心态消耗的總時間
第二個參數:結構體指針,用于指定計時器的新值;
struct itimerval
{
struct timeval it_interval; /* 間隔時間 */
struct timeval it_value; /* 開始時間 */
};
struct timeval
{
time_t tv_sec; /* 秒 */
suseconds_t tv_usec; /* 微秒 */
};
第三個參數:結構體指針,用于帶出設定之前的舊值;
1.5 擴充
(1)sigaction()
#include <signal.h>
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
- 功能:
- 主要用于設定信号的處理方式,signal()的增強版; 參數:
-
第一個參數:具體的信号值 / 信号名稱;(SIGKILL和SIGSTOP除外)
第二個參數:結構體指針,設定指定信号新的處理方式;
struct sigaction
{
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
struct siginfo_t
{
int si_signo; /* 信号值 */
...
}
第三個參數:結構體指針,擷取指定信号原來的處理方式;
(2)sigqueue()
#include <signal.h>
int sigqueue(pid_t pid, int sig, const union sigval value);
- 功能:
- 主要用于向指定的程序發送指定的信号,還可以帶一個附加資料; 參數:
-
第一個參數:指定程序的程序号;
第二個參數:具體的信号值 / 信号名稱,類似kill();
0 - - - - - 測試指定的程序是否存在
第三個參數:聯合類型,
union sigval
{
int sival_int;
void *sival_ptr;
};
… …
二、程序間的通信技術
2.1 基本概念
兩個 / 多個程序之間的資訊互動,就叫做程序間的通信;
2.2 通信方式
- 檔案
- 信号
- 管道
- 共享記憶體
- 消息隊列(重點)
- 信号量集
-
網絡(重點)
… …
其中4、5、6通信方式統稱為XSI IPC通信方式(X/open System Interface Inter-Process Communication)
練習:
嘗試查詢sigaction()的用法;
- 明日預報:
- (1)程序間的通信技術;