在 C 語言中傳送訊號到一個程序
本文將解釋幾種如何在 C 語言中將訊號傳送到程序的方法。
使用 kill
函式將訊號傳送到 C 語言中的程序
訊號是中斷樣式的通知,可以表示特定事件,並且可以將其傳送到程序。如果第一個程序具有正確的許可權,則一個程序可以向另一個程序傳送訊號。訊號是一種程序間通訊,可用於與不同程式,子程序或執行緒進行互動。kill
功能可用於向過程傳送各種訊號。它帶有兩個引數-要傳遞的程序 ID 和訊號號。請注意,訊號號是常量整數,定義為 SIG___
型別巨集。
在下面的示例中,我們演示了一個程式,該程式使用 fork
呼叫建立一個子程序,然後執行遞增整數的無限迴圈。同時,父程序發出 SIGTERM
訊號,終止子程序,並且在使用 waitpid
呼叫接收到子狀態程式碼後,主函式退出。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
int main(int argc, char *argv[]) {
int wstatus;
pid_t c_pid = fork();
if (c_pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (c_pid == 0) {
printf("printed from child process - %d\n", getpid());
int count = 0;
while (1) {
count += 1;
}
exit(EXIT_SUCCESS);
} else {
printf("printed from parent process - %d\n", getpid());
int ret;
ret = kill(c_pid, SIGTERM);
if (ret == -1) {
perror("kill");
exit(EXIT_FAILURE);
}
if (waitpid(c_pid, &wstatus, WUNTRACED | WCONTINUED) == -1) {
perror("waitpid");
exit(EXIT_FAILURE);
}
}
exit(EXIT_SUCCESS);
}
使用 kill
函式和空訊號來檢查 C 語言中程序的存在
kill
功能的另一個用例是檢查程序的存在。即使你嘗試使用此方法驗證某些程序的存在,在某些情況下,檢索到的狀態也不正確。這可能是由於觀察到的過程已經終止並且不同的程式使用了相同的 ID 而引起的,因為作業系統允許重複使用標識號。
需要向 kill
傳遞一個訊號編號-0
,並且應對函式的返回碼進行 errno
碼的測試。也就是說,如果 kill
返回 -1
錯誤程式碼,並且將 errno
設定為 ESRCH
,則給定的程序不存在。如果錯誤程式碼返回並帶有 errno
的 EPERM
值-程式存在,但是呼叫者程序沒有傳送訊號的許可。如果返回零,則該過程存在,並且呼叫者程序可以向其傳送其他訊號。
下面的程式碼示例實現上述狀態檢查語句並列印相應的訊息。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <stdbool.h>
int main(int argc, char *argv[]) {
int wstatus;
pid_t c_pid = fork();
if (c_pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (c_pid == 0) {
printf("printed from child process - %d\n", getpid());
int count = 10;
while (count >= 0) {
count -= 1;
sleep(1);
}
exit(EXIT_SUCCESS);
} else {
printf("printed from parent process - %d\n", getpid());
int ret;
errno = 0;
ret = kill(c_pid, 0);
if (ret == -1) {
if (errno == EPERM)
printf("Process exists, but we don't have "
"permission to send it a signal\n");
else if (errno == ESRCH)
printf("Process does not exist\n");
else
perror("kill");
exit(EXIT_FAILURE);
} else {
printf("Process exists and we can send it a signal\n");
}
if (waitpid(c_pid, &wstatus, WUNTRACED | WCONTINUED) == -1) {
perror("waitpid");
exit(EXIT_FAILURE);
}
}
exit(EXIT_SUCCESS);
}
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn