[英]Problems sending/handling signals across two processes on same computer - C programming
我在計算機上運行的兩個進程之間無法處理信號。 scheduler.c正在發送信號,producer.c接收它們。 生產者應該打印“打印n”,其中每收到SIGUSR1,n就會增加1。 我已經嘗試使用信號和信號處理信號,但是都沒有用。
scheduler.c:
/*
* scheduler.c
*/
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int n = 1;
int main(int argc, char *argv[])
{
int a = 0; // This variable will be used for the switch later
// Check to ensure correct number of command line arguments
if(argc != 2){
printf("Usage error. Wrong number of arguments\n");
return 1;
}
// Grab PID of producer.c
int producer_pid = atoi(argv[1]);
while(1){
printf("Choose an Option: \n");
printf("1. Request_Production\n");
printf("2. Stop_Producer\n");
printf("3. Stop_Scheduler\n");
scanf("%d", &a);
switch( a )
{
case 1:
kill(producer_pid, 16); //Send SIGUSR1 to producer.c
break;
case 2:
kill(producer_pid, 2); //Send SIGINT to producer.c
break;
// Successfully exit program
case 3:
return 0;
// Invalid Choice
default :
printf("Invalid choice\n");
}
}
}
producer.c:
/*
* producer.c
*/
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int n = 1;
void sigusr1(int signo)
{
printf("Producing %d", n);
n++;
}
int main()
{
struct sigaction act;
sigset_t block_mask;
sigfillset(&block_mask);
act.sa_handler = sigusr1;
act.sa_mask = block_mask;
act.sa_flags = 0;
if(sigaction(SIGUSR1, &act, NULL) == 0){
printf("success");
}
while(1) {
sleep(2);
fflush(stdout);
}
}
該代碼對我有用(在Mac OS X 10.7.5上):
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
static volatile sig_atomic_t n = 0;
static void sigusr1(int signo)
{
n += signo / SIGUSR1;
}
int main(void)
{
struct sigaction act;
sigset_t block_mask;
sigfillset(&block_mask);
act.sa_handler = sigusr1;
act.sa_mask = block_mask;
act.sa_flags = 0;
if (sigaction(SIGUSR1, &act, NULL) == 0)
{
printf("success %d\n", (int)getpid());
while (1)
{
pause();
printf("Producer: %d\n", n);
fflush(stdout);
}
}
}
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int a = 0; // This variable will be used for the switch later
// Check to ensure correct number of command line arguments
if (argc != 2)
{
fprintf(stderr, "Usage: %s pid\n", argv[0]);
return 1;
}
// Grab PID of producer.c
int producer_pid = atoi(argv[1]);
while(1)
{
printf("Choose an Option: \n");
printf("1. Request Production\n");
printf("2. Stop Producer\n");
printf("3. Stop Scheduler\n");
scanf("%d", &a);
switch (a)
{
case 1:
if (kill(producer_pid, SIGUSR1) != 0)
fprintf(stderr, "Failed to send signal %d to %d\n", SIGUSR1, producer_pid);
break;
case 2:
if (kill(producer_pid, SIGTERM) != 0)
fprintf(stderr, "Failed to send signal %d to %d\n", SIGTERM, producer_pid);
break;
// Successfully exit program
case 3:
return 0;
// Invalid Choice
default :
fprintf(stderr, "Invalid choice (%d)\n", a);
break;
}
}
}
$ (./producer &)
$ success 40119
$ ./scheduler 40119
Choose an Option:
1. Request Production
2. Stop Producer
3. Stop Scheduler
1
Choose an Option:
1. Request Production
2. Stop Producer
3. Stop Scheduler
Producer: 1
1
Choose an Option:
1. Request Production
2. Stop Producer
3. Stop Scheduler
Producer: 2
1
Choose an Option:
1. Request Production
2. Stop Producer
3. Stop Scheduler
Producer: 3
1
Choose an Option:
1. Request Production
2. Stop Producer
3. Stop Scheduler
Producer: 4
1
Choose an Option:
1. Request Production
2. Stop Producer
3. Stop Scheduler
Producer: 5
1
Choose an Option:
1. Request Production
2. Stop Producer
3. Stop Scheduler
Producer: 6
1
Choose an Option:
1. Request Production
2. Stop Producer
3. Stop Scheduler
Producer: 7
1
Choose an Option:
1. Request Production
2. Stop Producer
3. Stop Scheduler
Producer: 8
2
Choose an Option:
1. Request Production
2. Stop Producer
3. Stop Scheduler
1
Failed to send signal 30 to 40119
Choose an Option:
1. Request Production
2. Stop Producer
3. Stop Scheduler
3
$
進行了各種更改,但關鍵更改是:
n
為volatile sig_atomic_t
變量; 這就是C標准說的您可以在信號處理程序中訪問的內容。 pause()
,然后打印。 只有在被信號中斷時, pause()
系統調用才會返回。 SIGTERM
而不是SIGINT
終止生產者。 如果生產者在后台運行,則它會忽略中斷。 kill()
調用失敗。 我已經從文件標題中刪除了多余的標題。
信號處理程序中有趣的signo / SIGUSR1
避免了有關未使用參數的警告; 它沒有其他目的。 如圖所示,程序可以在以下環境下干凈地編譯:
gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition scheduler.c -o scheduler
gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition producer.c -o producer
這是使用GCC 4.7.1。
一句話:
有一些安全的函數,還有其他一些不安全的函數可以從信號處理程序中調用。
不能從信號處理程序中調用printf
。 另一方面write
是安全的。
該列表由POSIX-1指定,但不同的操作系統可能有所不同。 對於Linux,您可以在signal(7)中找到該列表:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.