Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用字符设备驱动程序捕捉信号和暂停_C_Linux_Signals_Linux Device Driver_Daemon - Fatal编程技术网

C 使用字符设备驱动程序捕捉信号和暂停

C 使用字符设备驱动程序捕捉信号和暂停,c,linux,signals,linux-device-driver,daemon,C,Linux,Signals,Linux Device Driver,Daemon,我是C编程的新手,不完全了解信号捕获的工作原理,也不完全了解字符设备驱动程序。我非常感谢您的帮助,但我需要声明,这是我第一次C编程课上的一个项目。因此,我没有发布任何直接代码,只是我最初方法的一个示例 #include <stdio.h> #include <unistd.h> #include <signal.h> #include <stdlib.h> static int file_state; //v

我是
C编程的新手
,不完全了解信号捕获的工作原理,也不完全了解字符设备驱动程序。我非常感谢您的帮助,但我需要声明,这是我第一次
C编程
课上的一个项目。因此,我没有发布任何直接代码,只是我最初方法的一个示例

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>

static int file_state;                    //variable to pass to the driver for recording

void sig_handler(int sig);        

void sig_handler(int sig){
    if(sig == SIGRTMIN){
        printf("SIG = SIGRTMIN\n");
        file_state = 0;
    }else if(sig == SIGRTMIN+1){
        printf("SIG = SIGRTMIN1\n");
        file_state = 1;
    }else if(sig == SIGTERM){
        exit(0);
        EXIT_SUCCESS;                     
    }else{
        printf("SIGNAL CAUGHT #%d\n", sig);
    }
}

int main(){
    if(signal(SIGRTMIN, sig_handler)==SIG_ERR){
         printf("Unable to catch SIGRTMIN\n");
    }
    if(signal(SIGRTMIN+1, sig_handler)==SIG_ERR){
         printf("Unable to catch SIGRTMIN+1\n");
    }
    if(signal(SIGTERM, sig_handler)==SIG_ERR){
         printf("Unable to terminate process.\n");
    }

    //This for loop will catch all other signals except the un-catchable and
    //other user-specified above signal #31.

    int s;
    for(s = 0; s < 32; s++){
         signal(s, sig_handler);
    }

    while(1);
    pause();
    return 0;
}
我的项目需要接受一个信号输入,并将该信号设置为一个变量,以传递给我的
字符设备驱动程序
。我编写的另一个程序需要访问该变量的值,以便在读取时执行特定的结果。我试图运行我的控制程序(
&
),但它立即退出。我通过在命令提示符中输入
ps
进行双重检查,该过程即告结束

基本上,我需要我的控制程序暂停,等待信号被接收。一旦收到,如果信号匹配,它将设置一个变量为其值。否则,如果它是
SIGTERM
,它将结束或
pause()
,在那里它将等待,直到收到满足另一条件的另一个信号。目前,当我使用
&
编译并运行它时,它只是运行并退出。下面是我的代码示例:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>

static int file_state;                    //variable to pass to the driver for recording

void sig_handler(int sig);        

void sig_handler(int sig){
    while(1){
        if(sig == SIGRTMIN){
            printf("SIG = SIGRTMIN\n");
            file_state = 0;
        }else if(sig == SIGRTMIN+1){
            printf("SIG = SIGRTMIN1\n");
            file_state = 1;
        }else if(sig == SIGTERM){
            printf("Exiting\n");
            exit(0);                         //exit
        }else{
            printf("SIG = %i\n", sig);
            pause();                        //doesn't match, pause for next signal
        }
    }
}

int main(){
    signal(SIGINT, sig_handler);
    //return 0;  //tried with and without
}
我正试图找出一种方法,使这个过程和信号捕获循环保持活动状态,直到收到特定的信号。我一辈子都搞不懂

ETA 2

发现了我的问题。我没有注意并完全理解
signal()
方法。第一个参数需要您试图捕获的确切信号。我使用的是
SIGINT
,我认为这是一个你想要捕捉的中断的“类”。然后在
signal\u handler()
函数中,指定捕获的中断类型。但是,它实际上是在寻找你感兴趣的确切信号。因此,在我的示例代码中,我应该使用:

int main(){
    if(signal(SIGRMIN, sig_handler) == SIG_ERR){
         printf("can't catch SIGRMIN Signal.\n")
    }
...
}

我将更新我的新脚本作为答案,如果有人认为应该以不同的方式进行,或者有任何建设性的批评,请让我知道。再次感谢

有两个部分,第一个用户空间,用于生成和捕获信号。这与内核驱动程序无关。你的代码似乎还可以


当信号被捕获时,第二个与驾驶员交互。对于char驱动程序,请看一下这个。您可以简单地编写一个值write(fd、1和buf);从用户空间程序,在char驱动程序中实现相应的write()。下面是我的固定代码,当被捕获时,它会向终端返回正确的响应。我已经添加了一个
for()
循环来捕获我不担心的任何其他信号。没有停止我的进程,只有
SIGTERM
会停止。期待被批评,以及为什么我永远不想做我的方法

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>

static int file_state;                    //variable to pass to the driver for recording

void sig_handler(int sig);        

void sig_handler(int sig){
    if(sig == SIGRTMIN){
        printf("SIG = SIGRTMIN\n");
        file_state = 0;
    }else if(sig == SIGRTMIN+1){
        printf("SIG = SIGRTMIN1\n");
        file_state = 1;
    }else if(sig == SIGTERM){
        exit(0);
        EXIT_SUCCESS;                     
    }else{
        printf("SIGNAL CAUGHT #%d\n", sig);
    }
}

int main(){
    if(signal(SIGRTMIN, sig_handler)==SIG_ERR){
         printf("Unable to catch SIGRTMIN\n");
    }
    if(signal(SIGRTMIN+1, sig_handler)==SIG_ERR){
         printf("Unable to catch SIGRTMIN+1\n");
    }
    if(signal(SIGTERM, sig_handler)==SIG_ERR){
         printf("Unable to terminate process.\n");
    }

    //This for loop will catch all other signals except the un-catchable and
    //other user-specified above signal #31.

    int s;
    for(s = 0; s < 32; s++){
         signal(s, sig_handler);
    }

    while(1);
    pause();
    return 0;
}
#包括
#包括
#包括
#包括
静态int文件_状态//要传递给驱动程序进行记录的变量
无效信号处理器(int sig);
无效信号处理器(int sig){
如果(sig==SIGRTMIN){
printf(“SIG=SIGRTMIN\n”);
文件状态=0;
}否则如果(sig==SIGRTMIN+1){
printf(“SIG=SIGRTMIN1\n”);
文件状态=1;
}else if(sig==SIGTERM){
出口(0);
成功退出;
}否则{
printf(“信号捕获#%d\n”,sig);
}
}
int main(){
if(信号(SIGRTMIN,sig_处理程序)=sig_ERR){
printf(“无法捕获SIGRTMIN\n”);
}
if(信号(SIGRTMIN+1,sig_处理程序)=sig_ERR){
printf(“无法捕获SIGRTMIN+1\n”);
}
if(信号(SIGTERM,sig_处理程序)=sig_ERR){
printf(“无法终止进程。\n”);
}
//该for循环将捕获除不可捕获和
//上述信号#31指定的其他用户。
int-s;
对于(s=0;s<32;s++){
信号(s、sig_处理器);
}
而(1),;
暂停();
返回0;
}

我想我不明白你的回答(顺便说一句,谢谢)。如果代码显示正常,为什么不暂停并保持打开状态?我一运行它,进程就关闭了,没有任何信号发送给它。关于第二点,我不能在基于捕获的信号链接的文件(进程、驱动程序、用户程序)中使用静态变量,还是应该写入设备驱动程序并从用户程序中引用该值?内核空间驱动程序和用户空间进度是两件完全不同的事情。它们只能通过linux内核提供的接口(系统调用)进行交互。所以我们需要有一个C源文件的用户程序和一个C源文件,这将是我们的驱动程序。是的,实际上我们的任务是使用三个文件。一个是信号控制器,它将向我的设备驱动程序发送功能信号(.ko扩展名和第二个文件),第三个文件是应用程序,它将从设备文件中读取。我正在尝试捕获信号(在收到有效信号后不关闭),并让设备驱动程序在读取时为我的应用程序提供正确的输出(同样,取决于捕获的信号)。您只能从信号处理程序中安全地调用异步信号安全函数。POSIX强制的异步信号安全函数可在以下位置找到:
printf()
不是异步信号安全的。@AndrewHenle感谢链接。老实说,我的
printf()
调用现在只是为我进行故障排除。然而,我不知道关于他们的细节。我只是想确保它工作正常,并且在收到不同的信号后,过程不会停止。