在同一台计算机上跨两个进程发送/处理信号的问题-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发送信号,producer.c接收信号。生产者应打印“打印n”,其中,每次收到SIGUSR1时,n将增加1。我曾尝试使用信号和sigaction来处理信号,但两者都不适用于我

调度程序.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");
        }
    }
}
/*
*调度程序.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()
    调用何时失败
  • 让生产商确定其PID
  • 我已经从文件标题中删除了多余的标题

    信号处理程序中有趣的
    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()
    调用何时失败
  • 让生产商确定其PID
  • 我已经从文件标题中删除了多余的标题

    信号处理程序中有趣的
    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