當前位置:首頁 » 操作系統 » signallinux

signallinux

發布時間: 2023-02-05 07:53:20

㈠ 關於linux中的signal函數

糾正一下:
輸出in sig_fun1:30就是第二次調用的時候輸出的,第一次調用只是綁定了SIGUSR1的信號處理函數,不會進入該處理函數

為什麼會有這樣的輸出呢?
signal函數是將信號與處理函數進行綁定,成功綁定則返回綁定之前的信號處理函數。那麼來看看你的代碼,第一次調用將sig_fun1綁定,無輸出;第二次調用將sig_fun2綁定,也就是把sig_fun1替換下來,並且你還調用了它,參數為30,所以會有那樣的輸出。

該如何改呢?
其實你並沒有涉及到linux的信號處理機制,光綁定是不夠的,還需要發信號給它,才能真正進入信號處理過程。給你一個示例代碼吧
#include<signal.h>
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>

void sig_fun2(int signo)
{
printf("in sig_fun2:%d\n", signo);
}

void sig_fun1(int signo)
{
printf("in sig_fun1:%d\n", signo);
}

int main()
{
unsigned long i;
if (signal(SIGUSR1, sig_fun1) == SIG_ERR)
{
printf("signal fun1 error\n");
exit(1);
}
sleep(15);

(signal(SIGUSR1, sig_fun2))(30);
sleep(15);

printf("done\n");
return 0;
}
/****************************C 代碼完,下面是如何運行***************************/
首先編譯,假設生成可執行程序為test
然後運行,我用的是後台運行: nohup ./test>output.txt &
注意,這種方法要將輸出重定向到文件output.txt(名字無所謂),然後你會看到一個數字,就是pid進程號
最後,在15秒之內發送信號:kill -SIGUSR1 進程號
現在你就可以打開output.txt看輸出結果了。如果用sleep的話會被打斷,所以只有兩個輸出加上替換處理函數時的輸出共3個,也可以換成 int n=15;while(n--)sleep(1);
-------------------------------------------------------------
怎麼樣,加分吧
-------------------------------------------------------------
1.我就是想問第二次綁定sig_fun2的時候,調用了第一次綁定的sig_fun1么?
調用了, (signal(SIGUSR1, sig_fun2))(30);就是這一句, signal(SIGUSR1, sig_fun2)是個函數指針,你這樣寫就是調用它了,但是這和信號處理沒關系,寫成signal(SIGUSR1, sig_fun2);就可以了
這就是你所說的成功則返回綁定之前的函數???

那當時綁定sig_fun1的時候,返回之前的處理函數是什麼??
這個就是系統默認的了,比如SIGINT就是你ctrl+c取消程序執行發送的信號,它的處理函數就是結束程序的一系列動作,不過SIGUSR1是留給用戶自定義的信號,系統默認應該是啥也不做的一個函數,例如void fun(int signo){},你也可以第一次綁定的時候就調用試試看對不對

2.還有我在看signal函數定義的時候,void(//...)(int) 最後傳入的這個int整形參數就是我們自定義sig_fun()中所接收的30么??我看例子裡面有的signal(SIGINT,myfunc);也沒有帶參數啊,搞不懂
是你理解錯了,signal函數只是綁定,沒涉及到調用綁定函數,不用帶參數,信號處理函數不是像你這樣調用的。callback回調你知道吧,就是先做好一個函數或過程放著,事件觸發的時候才調用。那個30是你用普通函數調用的方式時的參數,跟信號處理一點關系也沒有,你用60,70也沒半毛錢關系。我猜你是想要調用信號處理函數,然後迷糊了,其實我上面說的「kill -SIGUSR1 進程號」就是觸發程序調用該處理函數的信號,這和kill -9 殺死進程一個道理,只不過處理函數不同,結果不一樣。ctrl+c也可以用信號的方式發送,kill -2 進程號,或者 kill -SIGINT 進程號

㈡ linux signal 11 是什麼意思

通過kill -l 可以查看信號列表,11 是段錯誤
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD
18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN
22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO
30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1
36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5
40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9
44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13
52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9
56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5
60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1
64) SIGRTMAX

㈢ 問個關於linux signal的問題

不可能的,SIGSEGV表示你訪問了非法地址,只能捕獲信號提醒你發生什麼故障,信號處理返回後,你會繼續執行你非法訪問的代碼,繼續觸發SIGSEGV,要麼退出,要麼一直執行異常指令觸發信號,無法繼續往下執行。

補充:

setjmp 應用於信號處理是在那些非異常信號的上下文中,比如SIGUSR,SIGARLAM等,這些信號專門拿來做進程通信的,跟你這種運行中代碼異常觸發的異常信號不一樣的。你要setjmp的信號處理,例子也很多,richard steven的《unix 環境高級編程》裡面就有。

我估計你是沒找到那裡觸發的SIGSEGV,想規避,這個不是正路,也解決不了問題的!

㈣ Linux環境下使用signal函數進行進程間通信的問題

測試了一下,三個進程都會收到SIGINT信號。

原程序中,child1, child2都收到SIGINT信號,調用stop(), 之後被喚醒,列印"child process ... is killed by parent!",事實上kill這兩個child的不是parent,是它們自己的SIGINT。

放到①處,child1收到SIGINT信號,默認的行為是把自己殺了,當然也來不及列印任何東西了。child2收到SIGINT信號,打斷waiting(),列印"child process 2 ...",然後退出。殺死它的也不是SIGUSR2信號。

放到②處,child1, child2收到SIGINT信號,默認的行為是立即把自己殺了,也來不及列印任何東西了。

測試方法:

// 列印誰執行、被什麼信號打斷
static void stop(int signal) {
printf("stop %d by signal %d\n", getpid(), signal);
wait_mark=0;
}

// 在parent進程中,列印各進程id
printf("parent %d, child1 %d, child2 %d\n",getpid(),p1,p2);

如果讓parent成為殺死child的兇手,可以在child1,child2中加入:
signal(SIGINT, keep_me_alive);

// 不理睬SIGINT信號
static void keep_me_alive(int signal) {
}

這時列印結果就一樣了

㈤ linuxsignal的處理函數可以是非靜態嗎

不可以。linuxsignal的處理函數是響應於某個事件而調用的函數,由鍵盤觸發的事件,適用於所有HTML5元素。linuxsignal的處理函數是不可以是非靜態的,靜態函數就是函數調用的結果不會訪問或者修改任何對象(非static)數據成員,這樣的成員聲明為靜態成員函數比較好。

㈥ Linux進程間通信

linux下進程間通信的幾種主要手段簡介:

一般文件的I/O函數都可以用於管道,如close、read、write等等。

實例1:用於shell

管道可用於輸入輸出重定向,它將一個命令的輸出直接定向到另一個命令的輸入。比如,當在某個shell程序(Bourne shell或C shell等)鍵入who│wc -l後,相應shell程序將創建who以及wc兩個進程和這兩個進程間的管道。

實例二:用於具有親緣關系的進程間通信

管道的主要局限性正體現在它的特點上:

有名管道的創建

小結:

管道常用於兩個方面:(1)在shell中時常會用到管道(作為輸入輸入的重定向),在這種應用方式下,管道的創建對於用戶來說是透明的;(2)用於具有親緣關系的進程間通信,用戶自己創建管道,並完成讀寫操作。

FIFO可以說是管道的推廣,克服了管道無名字的限制,使得無親緣關系的進程同樣可以採用先進先出的通信機制進行通信。

管道和FIFO的數據是位元組流,應用程序之間必須事先確定特定的傳輸"協議",採用傳播具有特定意義的消息。

要靈活應用管道及FIFO,理解它們的讀寫規則是關鍵。

信號生命周期

信號是進程間通信機制中唯一的非同步通信機制,可以看作是非同步通知,通知接收信號的進程有哪些事情發生了。信號機制經過POSIX實時擴展後,功能更加強大,除了基本通知功能外,還可以傳遞附加信息。

可以從兩個不同的分類角度對信號進行分類:(1)可靠性方面:可靠信號與不可靠信號;(2)與時間的關繫上:實時信號與非實時信號。

(1) 可靠信號與不可靠信號

不可靠信號 :Linux下的不可靠信號問題主要指的是信號可能丟失。

可靠信號 :信號值位於SIGRTMIN和SIGRTMAX之間的信號都是可靠信號,可靠信號克服了信號可能丟失的問題。Linux在支持新版本的信號安裝函數sigation()以及信號發送函數sigqueue()的同時,仍然支持早期的signal()信號安裝函數,支持信號發送函數kill()。

對於目前linux的兩個信號安裝函數:signal()及sigaction()來說,它們都不能把SIGRTMIN以前的信號變成可靠信號(都不支持排隊,仍有可能丟失,仍然是不可靠信號),而且對SIGRTMIN以後的信號都支持排隊。這兩個函數的最大區別在於,經過sigaction安裝的信號都能傳遞信息給信號處理函數(對所有信號這一點都成立),而經過signal安裝的信號卻不能向信號處理函數傳遞信息。對於信號發送函數來說也是一樣的。

(2) 實時信號與非實時信號

前32種信號已經有了預定義值,每個信號有了確定的用途及含義,並且每種信號都有各自的預設動作。如按鍵盤的CTRL ^C時,會產生SIGINT信號,對該信號的默認反應就是進程終止。後32個信號表示實時信號,等同於前面闡述的可靠信號。這保證了發送的多個實時信號都被接收。實時信號是POSIX標準的一部分,可用於應用進程。非實時信號都不支持排隊,都是不可靠信號;實時信號都支持排隊,都是可靠信號。

發送信號的主要函數有:kill()、raise()、 sigqueue()、alarm()、setitimer()以及abort()。

調用成功返回 0;否則,返回 -1。

sigqueue()是比較新的發送信號系統調用,主要是針對實時信號提出的(當然也支持前32種),支持信號帶有參數,與函數sigaction()配合使用。

sigqueue的第一個參數是指定接收信號的進程ID,第二個參數確定即將發送的信號,第三個參數是一個聯合數據結構union sigval,指定了信號傳遞的參數,即通常所說的4位元組值。

sigqueue()比kill()傳遞了更多的附加信息,但sigqueue()只能向一個進程發送信號。sigqueue()比kill()傳遞了更多的附加信息,但sigqueue()只能向一個進程發送信號。

inux主要有兩個函數實現信號的安裝: signal() sigaction() 。其中signal()在可靠信號系統調用的基礎上實現, 是庫函數。它只有兩個參數,不支持信號傳遞信息,主要是用於前32種非實時信號的安裝;而sigaction()是較新的函數(由兩個系統調用實現:sys_signal以及sys_rt_sigaction),有三個參數,支持信號傳遞信息,主要用來與 sigqueue() 系統調用配合使用,當然,sigaction()同樣支持非實時信號的安裝。sigaction()優於signal()主要體現在支持信號帶有參數。

消息隊列就是一個消息的鏈表。可以把消息看作一個記錄,具有特定的格式以及特定的優先順序。對消息隊列有寫許可權的進程可以向中按照一定的規則添加新消息;對消息隊列有讀許可權的進程則可以從消息隊列中讀走消息。消息隊列是隨內核持續的

消息隊列的內核持續性要求每個消息隊列都在系統范圍內對應唯一的鍵值,所以,要獲得一個消息隊列的描述字,只需提供該消息隊列的鍵值即可;

消息隊列與管道以及有名管道相比,具有更大的靈活性,首先,它提供有格式位元組流,有利於減少開發人員的工作量;其次,消息具有類型,在實際應用中,可作為優先順序使用。這兩點是管道以及有名管道所不能比的。同樣,消息隊列可以在幾個進程間復用,而不管這幾個進程是否具有親緣關系,這一點與有名管道很相似;但消息隊列是隨內核持續的,與有名管道(隨進程持續)相比,生命力更強,應用空間更大。

信號燈與其他進程間通信方式不大相同,它主要提供對進程間共享資源訪問控制機制。相當於內存中的標志,進程可以根據它判定是否能夠訪問某些共享資源,同時,進程也可以修改該標志。除了用於訪問控制外,還可用於進程同步。信號燈有以下兩種類型:

int semop(int semid, struct sembuf *sops, unsigned nsops); semid是信號燈集ID,sops指向數組的每一個sembuf結構都刻畫一個在特定信號燈上的操作。

int semctl(int semid,int semnum,int cmd,union semun arg)
該系統調用實現對信號燈的各種控制操作,參數semid指定信號燈集,參數cmd指定具體的操作類型;參數semnum指定對哪個信號燈操作,只對幾個特殊的cmd操作有意義;arg用於設置或返回信號燈信息。

進程間需要共享的數據被放在一個叫做IPC共享內存區域的地方,所有需要訪問該共享區域的進程都要把該共享區域映射到本進程的地址空間中去。系統V共享內存通過shmget獲得或創建一個IPC共享內存區域,並返回相應的標識符。內核在保證shmget獲得或創建一個共享內存區,初始化該共享內存區相應的shmid_kernel結構注同時,還將在特殊文件系統shm中,創建並打開一個同名文件,並在內存中建立起該文件的相應dentry及inode結構,新打開的文件不屬於任何一個進程(任何進程都可以訪問該共享內存區)。所有這一切都是系統調用shmget完成的。

shmget()用來獲得共享內存區域的ID,如果不存在指定的共享區域就創建相應的區域。shmat()把共享內存區域映射到調用進程的地址空間中去,這樣,進程就可以方便地對共享區域進行訪問操作。shmdt()調用用來解除進程對共享內存區域的映射。shmctl實現對共享內存區域的控制操作。這里我們不對這些系統調用作具體的介紹,讀者可參考相應的手冊頁面,後面的範例中將給出它們的調用方法。

註:shmget的內部實現包含了許多重要的系統V共享內存機制;shmat在把共享內存區域映射到進程空間時,並不真正改變進程的頁表。當進程第一次訪問內存映射區域訪問時,會因為沒有物理頁表的分配而導致一個缺頁異常,然後內核再根據相應的存儲管理機制為共享內存映射區域分配相應的頁表。

㈦ linux signal(SIGINT,SIG_IGN);大概解釋一下

signal,此函數相對簡單一些,給定一個信號,給出信號處理函數則可,當然,函數簡單,其功能也相對簡單許多,簡單給出個函數例子如下:

#include<signal.h>
#include<stdio.h>
#include<unistd.h>

voidouch(intsig)
{
printf("Igotsignal%d ",sig);
//(void)signal(SIGINT,SIG_DFL);
//(void)signal(SIGINT,ouch);

}

intmain()
{
(void)signal(SIGINT,ouch);

while(1)
{
printf("helloworld... ");
sleep(1);
}
}

當然,實際運用中,需要對不同到signal設定不同的到信號處理函數,SIG_IGN忽略/SIG_DFL默認,這倆宏也可以作為信號處理函數。同時SIGSTOP/SIGKILL這倆信號無法捕獲和忽略。注意,經過實驗發現,signal函數也會堵塞當前正在處理的signal,但是沒有辦法阻塞其它signal,比如正在處理SIG_INT,再來一個SIG_INT則會堵塞,但是來SIG_QUIT則會被其中斷,如果SIG_QUIT有處理,則需要等待SIG_QUIT處理完了,SIG_INT才會接著剛才處理。

㈧ Linux中signal()如何捕捉鍵盤上的del鍵

int catch( int sig )
{
printf("recv del\n" );
}

int main()
{
signal( SIG_INT, catch );
while( getchar() != '\n' ) ;
return 0;
}

按回車結束程序,按Del會輸出recv del。

㈨ linux中的signal怎麼使用

signal函數的定義很復雜,但是它的用法還是比較簡單的,你記住它的兩個參數就可以了。signal有兩個參數sig和func,signal這個函數是用來接收信號並處理的,所以sig參數表示將要處理哪種類型的信號,而func參數是一個函數指針,用來指定信號的處理函數,也就是當程序接收到sig那個類型的信號後,就會調用func指針指向的函數。func指針的原型是:
void (*func) (int)
所以信號的處理函數必須是一個返回void,只有一個int類型參數的函數。
比如如果程序需要處理Ctrl+C組合鍵產生的信號,就可以這樣使用signal函數:
(void) signal(SIGINT, myfunc);
而myfunc函數可以這樣定義:
void myfunc(int sig)
{
printf("Hello, the signal is %d\n", sig);
// 因為現在處理的是Ctrl+C信號,所以下面要
// 恢復程序對Ctrl+C的默認反應
(void) signal(SIGINT, SIG_DFL);
}

㈩ Linux下signal信號匯總

Linux下signal信號匯總
SIGHUP 1 /* Hangup (POSIX). / 終止進程 終端線路掛斷
SIGINT 2 /
Interrupt (ANSI). / 終止進程 中斷進程 Ctrl+C
SIGQUIT 3 /
Quit (POSIX). / 建立CORE文件終止進程,並且生成core文件 Ctrl+
SIGILL 4 /
Illegal instruction (ANSI). / 建立CORE文件,非法指令
SIGTRAP 5 /
Trace trap (POSIX). / 建立CORE文件,跟蹤自陷
SIGABRT 6 /
Abort (ANSI). /
SIGIOT 6 /
IOT trap (4.2 BSD). / 建立CORE文件,執行I/O自陷
SIGBUS 7 /
BUS error (4.2 BSD). / 建立CORE文件,匯流排錯誤
SIGFPE 8 /
Floating-point exception (ANSI). / 建立CORE文件,浮點異常
SIGKILL 9 /
Kill, unblockable (POSIX). / 終止進程 殺死進程
SIGUSR1 10 /
User-defined signal 1 (POSIX). / 終止進程 用戶定義信號1
SIGSEGV 11 /
Segmentation violation (ANSI). / 建立CORE文件,段非法錯誤
SIGUSR2 12 /
User-defined signal 2 (POSIX). / 終止進程 用戶定義信號2
SIGPIPE 13 /
Broken pipe (POSIX). / 終止進程 向一個沒有讀進程的管道寫數據
SIGALARM 14 /
Alarm clock (POSIX). / 終止進程 計時器到時
SIGTERM 15 /
Termination (ANSI). / 終止進程 軟體終止信號
SIGSTKFLT 16 /
Stack fault. /
SIGCLD SIGCHLD /
Same as SIGCHLD (System V). /
SIGCHLD 17 /
Child status has changed (POSIX). / 忽略信號 當子進程停止或退出時通知父進程
SIGCONT 18 /
Continue (POSIX). / 忽略信號 繼續執行一個停止的進程
SIGSTOP 19 /
Stop, unblockable (POSIX). / 停止進程 非終端來的停止信號
SIGTSTP 20 /
Keyboard stop (POSIX). / 停止進程 終端來的停止信號 Ctrl+Z
SIGTTIN 21 /
Background read from tty (POSIX). / 停止進程 後台進程讀終端
SIGTTOU 22 /
Background write to tty (POSIX). / 停止進程 後台進程寫終端
SIGURG 23 /
Urgent condition on socket (4.2 BSD). / 忽略信號 I/O緊急信號
SIGXCPU 24 /
CPU limit exceeded (4.2 BSD). / 終止進程 CPU時限超時
SIGXFSZ 25 /
File size limit exceeded (4.2 BSD). / 終止進程 文件長度過長
SIGVTALRM 26 /
Virtual alarm clock (4.2 BSD). / 終止進程 虛擬計時器到時
SIGPROF 27 /
Profiling alarm clock (4.2 BSD). / 終止進程 統計分布圖用計時器到時
SIGWINCH 28 /
Window size change (4.3 BSD, Sun). / 忽略信號 窗口大小發生變化
SIGPOLL SIGIO /
Pollable event occurred (System V). /
SIGIO 29 /
I/O now possible (4.2 BSD). / 忽略信號 描述符上可以進行I/O
SIGPWR 30 /
Power failure restart (System V). /
SIGSYS 31 /
Bad system call. */
SIGUNUSED 31

有兩個信號可以停止進程:SIGTERM和SIGKILL。 SIGTERM 比較友好,進程能捕捉這個信號,根據您的需要來關閉程序。

在關閉程序之前,您可以結束打開的記錄文件和完成正在做的任務。在某些情況下,假如進程正在進行作業而且不能中斷,那麼進程可以忽略這個SIGTERM信號。

對於 SIGKILL 信號,進程是不能忽略的。這是一個 「我不管您在做什麼,立刻停止」的信號。假如您發送SIGKILL信號給進程,Linux就將進程停止在那裡。

sigaddset 將信號signo 加入到信號集合之中;
sigdelset 將信號從信號集合中刪除;
sigemptyset 函數初始化信號集合set,將set 設置為空;
sigfillset 也初始化信號集合,只是將信號集合設置為所有信號的集合;

熱點內容
如何提高手機緩存速度 發布:2025-07-18 20:24:48 瀏覽:236
vba讀取資料庫數據 發布:2025-07-18 20:24:48 瀏覽:607
shell解壓zip 發布:2025-07-18 20:20:36 瀏覽:858
安卓泰拉瑞亞去哪裡買 發布:2025-07-18 20:01:05 瀏覽:694
flash編譯器 發布:2025-07-18 19:49:38 瀏覽:487
memcached源碼分析 發布:2025-07-18 19:22:42 瀏覽:866
android展示圖片 發布:2025-07-18 19:21:24 瀏覽:594
一台伺服器5個IP怎麼分配 發布:2025-07-18 19:12:34 瀏覽:862
貴陽分布式存儲行情 發布:2025-07-18 19:12:31 瀏覽:361
車場伺服器和工控機是如何連接的 發布:2025-07-18 19:10:19 瀏覽:938