1.1 kill
kill
函數(shù)是UNIX和類UNIX操作系統(tǒng)中的一個標(biāo)準(zhǔn)庫函數(shù),主要用于向指定進(jìn)程發(fā)送信號。
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int signum);
pid_t pid
?是進(jìn)程ID,int signum
?是信號的編號。
kill
函數(shù)的作用是將signum
指定的信號發(fā)送到pid
指定的進(jìn)程。
-
pid > 0
:將信號發(fā)送給進(jìn)程ID為pid
的進(jìn)程。 -
pid = 0
:將信號發(fā)送給當(dāng)前進(jìn)程所在的整個進(jìn)程組中的所有進(jìn)程。 -
pid < 0
:將信號發(fā)送給進(jìn)程組ID等于pid
的絕對值的進(jìn)程組中的所有進(jìn)程。 -
pid = -1
:將信號發(fā)送給系統(tǒng)中的所有進(jìn)程,這個進(jìn)程組號等于pid的絕對值。
kill
函數(shù)的成功返回值為0,失敗返回值為-1
此外,調(diào)用kill
函數(shù)的進(jìn)程必須有權(quán)限向目標(biāo)進(jìn)程發(fā)送信號。通常,只有root用戶才能向所有進(jìn)程發(fā)送信號,而非root用戶只能向與自己用戶ID相同的進(jìn)程發(fā)送信號
案例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
int main()
{
pid_t pid;
pid = fork();
if(pid < 0)
{
perror("fail to fork");
exit(1);
}
else if(pid > 0) //父進(jìn)程的代碼區(qū)
{
while(1)
{
printf("This is parent peocess\n");
sleep(1);
}
}
else //子進(jìn)程的代碼區(qū)
{
printf("This is son process\n");
//子進(jìn)程在3秒之后,讓父進(jìn)程退出
sleep(3);
//使用kill給父進(jìn)程發(fā)送信號,然后父進(jìn)程接收到信號后直接退出就可以了
kill(getppid(), SIGINT);
}
return 0;
}
執(zhí)行結(jié)果
?1.2?alarm函數(shù)
alarm
函數(shù)是UNIX和類UNIX系統(tǒng)中的一種標(biāo)準(zhǔn)庫函數(shù),它的主要作用是為當(dāng)前進(jìn)程設(shè)置一個定時器。
當(dāng)設(shè)定時間到達(dá)后,定時器會向當(dāng)前進(jìn)程發(fā)送SIGALRM信號。
這個信號的默認(rèn)行為是終止進(jìn)程,但如果進(jìn)程中有一個已注冊的信號處理函數(shù)來處理SIGALRM信號,那么進(jìn)程會根據(jù)該函數(shù)的邏輯來執(zhí)行相應(yīng)的操作
#include <sys/time.h>
unsigned int alarm(unsigned int seconds);
seconds
參數(shù)
指定了定時器的超時時間,單位是秒。
如果seconds
的值為0,那么之前設(shè)置的定時器會被取消,并且返回之前定時器剩余的時間。
如果seconds
的值為-1,那么返回的是0
alarm
函數(shù)的返回值有以下幾種情況:
- 如果
seconds
的值為0,返回值也是0。 - 如果
seconds
的值大于0,并且在seconds
秒內(nèi)再次調(diào)用了alarm
函數(shù)設(shè)置了新的定時器,那么返回值是之前定時器剩余的秒數(shù)。 - 如果
seconds
的值大于0,并且沒有在seconds
秒內(nèi)再次調(diào)用alarm
函數(shù)設(shè)置新的定時器,那么返回值是0
案例
#include <stdio.h>
#include <unistd.h>
#int main()
{
unsigned int sec;
//當(dāng)執(zhí)行到alarm之后,代碼會接著往下執(zhí)行,當(dāng)設(shè)定的時間到后,會產(chǎn)生SIGALRM信
//如果alarm之前沒有設(shè)置其他鬧鐘,則返回0,如果之前設(shè)置了,則返回之前剩余的
//如果一個程序中出現(xiàn)多個alarm鬧鐘,第一個如果沒有到達(dá)指定的時間就遇到第二個
//則第一個的鬧鐘時間清除,按照第二個alarm鬧鐘的時間繼續(xù)向下運行
sec = alarm(5);
printf("sec = %d\n", sec);
sleep(3);
sec = alarm(6);
printf("sec = %d\n", sec);
while(1)
{
printf("hello world\n");
sleep(1);
}
return 0;
}
執(zhí)行結(jié)果
??1.3?raise函數(shù)
raise
函數(shù)主要用于向當(dāng)前進(jìn)程發(fā)送一個信號。這個函數(shù)的原型如下:
#include <signal.h>
int raise(int sig);
sig
參數(shù)是你想要發(fā)送的信號的名字
。這個函數(shù)的工作原理是,當(dāng)你調(diào)用raise
函數(shù)并傳入一個特定的信號名時,它會向當(dāng)前進(jìn)程發(fā)送這個信號
返回值: ?成功:0 ?
????????????????失敗:非0
raise(sig)? 等同于? ?kill(getpid(),?sig)
案例
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char const *argv[])
{
int num = 0;
while(1)
{
printf("hello world\n");
sleep(1);
num++;
//當(dāng)循環(huán)執(zhí)行5秒后,進(jìn)程退出
if(num == 5)
{
//使用raise給當(dāng)前進(jìn)程本身發(fā)送信號
raise(SIGALRM);
//等同于kill(getpid(), SIGALRM);
}
}
return 0;
}
執(zhí)行結(jié)果
1.4 abort函數(shù)?
abort
函數(shù)是C語言中的一個標(biāo)準(zhǔn)庫函數(shù),其原型定義在<stdlib.h>
頭文件中。
該函數(shù)的主要作用是使當(dāng)前的進(jìn)程異常終止,即立即停止當(dāng)前正在執(zhí)行的程序,而不進(jìn)行正常的資源回收和清理工作。
#include <stdlib.h>
void abort(void);
功能:向進(jìn)程發(fā)送一個SIGABRT信號,默認(rèn)情況下進(jìn)程會退出。
參數(shù):無
返回值:無
?注意: 即使SIGABRT信號被加入阻塞集,一旦進(jìn)程調(diào)用了abort函數(shù),進(jìn)程也還是會被終止, 且在終止前會刷新緩沖區(qū),關(guān)閉文件描述符。
案例
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
int num = 0;
while(1)
{
printf("hello world\n");
sleep(1);
num++;
//當(dāng)循環(huán)執(zhí)行5秒后,進(jìn)程退出
if(num == 5)
{
abort();
}
}
return 0;
}
執(zhí)行結(jié)果
1.5?pause函數(shù)
pause
函數(shù)作用是使當(dāng)前進(jìn)程進(jìn)入等待狀態(tài),直到接收到一個信號為止。
這個函數(shù)通常用于等待某個特定的事件發(fā)生,例如等待用戶輸入或者等待某個條件滿足。
#include <sys/wait.h>
int pause(void);
返回值: 當(dāng)有信號產(chǎn)生時,函數(shù)返回‐1
案例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
int main()
{
pid_t pid;
pid = fork();
if(pid < 0)
{
perror("fail to fork");
exit(1);
}
else if(pid > 0) //父進(jìn)程的代碼區(qū)
{
printf("This is parent peocess\n");
//使用pause阻塞等待捕捉信號
pause();
}
else //子進(jìn)程的代碼區(qū)
{
printf("This is son process\n");
sleep(3);
kill(getppid(), SIGINT);//睡眠三秒后殺死父進(jìn)程
}
return 0;
}
執(zhí)行結(jié)果
1.6?signal函數(shù)
signal
函數(shù)是用于設(shè)置一個特定的信號處理函數(shù)的標(biāo)準(zhǔn)庫函數(shù)。
當(dāng)進(jìn)程接收到一個信號時,signal
函數(shù)允許你指定一個函數(shù)來處理這個信號。
#include <signal.h>
void (*signal(int sig, void (*func)(int)))(int);
‐‐>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
功能:當(dāng)進(jìn)程中產(chǎn)生某一個信號時,對當(dāng)前信號進(jìn)行處理
參數(shù):
sig:指定要處理的信號
handler:處理方式
SIG_IGN 當(dāng)信號產(chǎn)生時,以缺省(忽略)的方式處理
SIG_DFL 當(dāng)信號產(chǎn)生時,以當(dāng)前信號默認(rèn)的方式處理
func
是你想要設(shè)置的信號處理函數(shù)。信號處理函數(shù)必須具有以下形式
void func(int sig);
當(dāng)信號產(chǎn)生時,通過信號處理函數(shù)自定義方式處理,函數(shù)名可以隨便寫,參數(shù)表示當(dāng)前的信號
?返回值: 成功:返回函數(shù)地址,該地址為此信號上一次注冊的信號處理函數(shù)的地址
? ? ? ? ? ? ? ? ?失?。篠IG_ERR文章來源:http://www.zghlxwxcb.cn/news/detail-856351.html
1.6.1??signal函數(shù)的使用
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
void handler(int sig);
int main(int argc, char const *argv[])
{
//以默認(rèn)的方式處理信號
#if 0
if(signal(SIGINT, SIG_DFL) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
if(signal(SIGQUIT, SIG_DFL) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
if(signal(SIGTSTP, SIG_DFL) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
#endif
//以忽略的方式來處理信號
#if 0
if(signal(SIGINT, SIG_IGN) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
if(signal(SIGQUIT, SIG_IGN) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
if(signal(SIGTSTP, SIG_IGN) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
//注意:SIGKILL和SIGSTOP這兩個信號只能以默認(rèn)的方式處理,不能忽略或者捕捉
// if(signal(SIGKILL, SIG_IGN) == SIG_ERR)
// {
// perror("fail to signal");
// exit(1);
// }
#endif
//以用戶自定義方式處理信號
#if 1
if(signal(SIGINT, handler) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
if(signal(SIGQUIT, handler) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
if(signal(SIGTSTP, handler) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
#endif
while(1)
{
printf("hello world\n");
sleep(1);
}
return 0;
}
void handler(int sig)
{
if(sig == SIGINT)
{
printf("SIGINT正在處理\n");
}
if(sig == SIGQUIT)
{
printf("SIGQUIT正在處理\n");
}
if(sig == SIGTSTP)
{
printf("SIGTSTP正在處理\n");
}
}
在使用signal
函數(shù)時,還需要考慮信號處理的同步和互斥問題,以確保程序的正確性和穩(wěn)定性文章來源地址http://www.zghlxwxcb.cn/news/detail-856351.html
到了這里,關(guān)于kill,alarm,raise,abort,pause,signal等函數(shù)的使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!