在同一台计算机上跨两个进程发送/处理信号的问题-C编程
我在处理计算机上运行的两个进程之间的信号时遇到问题。scheduler.c发送信号,producer.c接收信号。生产者应打印“打印n”,其中,每次收到SIGUSR1时,n将增加1。我曾尝试使用信号和sigaction来处理信号,但两者都不适用于我 调度程序.c:在同一台计算机上跨两个进程发送/处理信号的问题-C编程,c,signals,kill,interprocess,C,Signals,Kill,Interprocess,我在处理计算机上运行的两个进程之间的信号时遇到问题。scheduler.c发送信号,producer.c接收信号。生产者应打印“打印n”,其中,每次收到SIGUSR1时,n将增加1。我曾尝试使用信号和sigaction来处理信号,但两者都不适用于我 调度程序.c: /* * scheduler.c */ #include <signal.h> #include <string.h> #include <stdio.h> #include <uni
/*
* 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");
}
}
}
/*
*调度程序.c
*/
#包括
#包括
#包括
#包括
#包括
#包括
int n=1;
int main(int argc,char*argv[])
{
int a=0;//此变量稍后将用于开关
//检查以确保命令行参数的数量正确
如果(argc!=2){
printf(“使用错误。参数数目错误\n”);
返回1;
}
//producer.c的抓取PID
int producer_pid=atoi(argv[1]);
而(1){
printf(“选择一个选项:\n”);
printf(“1.请求\u生产”);
printf(“2.Stop\u Producer\n”);
printf(“3.停止计划程序\n”);
scanf(“%d”和“&a”);
开关(a)
{
案例1:
kill(producer_pid,16);//将SIGUSR1发送到producer.c
打破
案例2:
kill(producer_pid,2);//将SIGINT发送到producer.c
打破
//成功退出程序
案例3:
返回0;
//无效选择
违约:
printf(“无效选择\n”);
}
}
}
生产者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);
}
}
/*
*制作人
*/
#包括
#包括
#包括
#包括
#包括
#包括
int n=1;
无效信号1(内部信号)
{
printf(“生产%d”,n);
n++;
}
int main()
{
结构动作法;
sigset_t块遮罩;
sigfillset(&block_mask);
act.sa_handler=sigusr1;
act.sa_mask=块_mask;
act.sa_标志=0;
if(sigaction(SIGUSR1,&act,NULL)==0){
printf(“成功”);
}
而(1){
睡眠(2);
fflush(stdout);
}
}
一句话:
有些函数是安全的,有些函数是不安全的,可以从信号处理程序调用
printf
不能从信号处理程序调用<另一方面,代码>写入是安全的
该列表由POSIX-1指定,但详细信息可能因操作系统而异。对于Linux,您将在信号(7)中找到列表:
有一句话:
有些函数是安全的,有些函数是不安全的,可以从信号处理程序调用
printf
不能从信号处理程序调用<另一方面,代码>写入是安全的
该列表由POSIX-1指定,但详细信息可能因操作系统而异。对于Linux,您将在信号(7)中找到列表:
此代码适用于我(在Mac OS X 10.7.5上):
制作人
什么改变了?
各种变化,但关键是:
n
成为volatile sig\u atomic\u 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
这是在使用GCC4.7.1。这段代码对我很有用(在Mac OS X 10.7.5上):
制作人
什么改变了?
各种变化,但关键是:
n
成为volatile sig\u atomic\u 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
这是在使用GCC4.7.1。如何将write与int变量n一起使用?由于函数被调用为写入(int fd,char*buf,int num_bytes)我不知道变量
n
在哪里…sprintf(缓冲区,“%d”,n);写入(fd、缓冲区、len)代码>应该可以。或者一些人做你自己的sprintf
——比如处理单个整数。仍然什么都不做……我认为printf不一定是最好的problem@midma101printf不是这里的问题,但它无效anyway@vonbrand信号处理程序中也不允许使用sprintf。虽然我不知道为什么(某些实现可能在内部使用malloc…?),但我如何使用write with int变量n?函数被这样调用write(intfd,char*buf,intnum\u字节)
$ (./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
$
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