如何通过向他发送SIGUSR1信号立即唤醒守护进程

问题描述 投票:-1回答:1

我写了一个程序deamon,它将一个文件夹的文件复制到另一个文件夹。我必须实现SIGUSR1,它立即通过向他发送SIGUSR1信号唤醒守护进程。我不知道我做错了什么,我使用命令kill -SIGUSR1,也许是错误的命令?。有人知道这段代码有什么问题吗?编译完这个程序后我没有任何警告,但什么也没发生

 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <syslog.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <dirent.h>
#include <fcntl.h>
#include <signal.h>

#define _XOPEN_SOURCE ;

int recursion = 0; //1 if enabled, otherwise 0
int sleepTime = 300;
int fileLimit = 0;
int signaL = 0;
int exitSignal = 0;
int buffer = 1000;

//Returns 0 if arguments are correct otherwise returns 1
int readArguments(int number, char **argv, char *source, char *goal);
int checkFileType(struct stat file);
int copy(char *source, char *target, mode_t mask);
int copy_map(char *source, char *target, struct stat *Source);
void syncCopy(char *source, char *target);
void syncRemove(char *source, char *target);


void my_handler(int sig)
{
    syslog(LOG_INFO, "Daemon received signal SIGUSR1\n");
    signaL = 1;
}

void exitFunction(int sig)
{
    syslog(LOG_INFO, "Daemon received signal SIGUSR2\n");
    exitSignal = 1;
}
int main(int argc, char **argv)
{
    //char tables for paths
    char source[500], goal[500];
    struct stat Source, Goal;
    struct sigaction my_action, old_action;

    //checking and reading arguments
    if (readArguments(argc, argv, source, goal) == 1)
        exit(-1);

    //checking paths

    //checking  if argv[1] and argv[2] are existing paths
    if (lstat(source, &Source) != 0 || lstat(goal, &Goal) != 0) //bad result
    {
        printf("One of the paths or both dont exist\n");
        exit(-1);
    }

    if (checkFileType(Source) != 0)
    {
        printf("Source path is not path to folder");
        exit(-1);
    }

    if (checkFileType(Goal) != 0)
    {
        printf("Goal path is not path to folder");
        exit(-1);
    }

    //forking the parent process
    pid_t pid;
    // Fork off the parent process  and create new
    pid = fork();
    //if failure
    if (pid < 0)
    {
        exit(-1);
    }
    // if it is native process
    else if (pid > 0)
    {
        return 0;
    }
    //if pid==0 then it is childs process

    //now we have to umask in order to write to any files(for exmaple logs)

    umask(0);
    openlog("logFile", LOG_PID, LOG_DAEMON);
    syslog(LOG_INFO, "Deamon has just started running\n");

    pid_t sid = setsid();
    if (sid < 0)
    {
        syslog(LOG_ERR, "Error with session opening\n");
        exit(-1);
    }

    //SIGNAL SIGUSR1
    my_action.sa_handler = my_handler;
    sigfillset(&my_action.sa_mask);
    my_action.sa_flags = 0;
    if (sigaction(SIGUSR1, &my_action, &old_action) < 0)
    {
        syslog(LOG_ERR, "Error with the use of  SIGUSR1 signal\n");
        exit(-1);
    }

    //SIGNAL SIGUSR2 for exiting daemon
    my_action.sa_handler = exitFunction;
    sigfillset(&my_action.sa_mask);
    my_action.sa_flags = 0;
    if (sigaction(SIGUSR2, &my_action, &old_action) < 0)
    {
        syslog(LOG_ERR, "Error with the use of  SIGUSR2 signal\n");
        exit(-1);
    }

    while (!exitSignal)
    {
        sleep(sleepTime);
        switch (signaL)
        {
        case 0:
            syslog(LOG_INFO, "Demon started working after %ds\n", sleepTime);
            break;

        case 1:
        {
            syslog(LOG_INFO, "Demon started working after SIGUSR1 signal\n");
            signaL = 0; //Need to reeset signaL
            break;
        }
        }

        syncCopy(source, goal);
        syncRemove(source, goal);
        syslog(LOG_INFO, "Demon has just  gone to sleep");
    }

    //at the end of program we need to close log using
    syslog(LOG_INFO, "Demon has stopped\n");
    closelog();

    return 0;
}
c linux signals
1个回答
0
投票

使用kill -10 <pid>SIGUSR1kill -12 <pid>SIGUSR2命令。

 kill -l // command to know the signal number.

同时使变量signaLexitSignalvolatile sig_atomic_t类型。

为什么volatile

当在某个其他函数中定期检查信号处理程序中更新的全局变量以进行适当的操作时,我们应该始终使用volatile属性声明它们,以防止编译器执行导致变量存储在寄存器中的优化。在最坏的情况下,变量的更新值(在处理程序上下文中更新)对于变量的函数轮询是不可见的。

为什么sig_atomic_t

读取和写入全局变量可能涉及多个机器语言指令,并且信号处理程序可以在这样的指令序列的中间中断主程序。 (我们说对变量的访问是非原子的。)因此,C语言标准和SUSv3指定整数数据类型sig_atomic_t,其读写保证是原子的。因此,主程序和信号处理程序之间共享的全局标志变量应声明如下:

volatile sig_atomic_t signaL;

© www.soinside.com 2019 - 2024. All rights reserved.