【问题标题】:how to immediately wake up the daemon by sending him a SIGUSR1 signal如何通过向他发送 SIGUSR1 信号立即唤醒守护进程
【发布时间】:2019-04-15 07:48:53
【问题描述】:

我编写了一个程序守护程序,它将带有一个文件夹的文件复制到另一个文件夹。我必须实现 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】:

将命令用作kill -10 &lt;pid&gt; 用于SIGUSR1kill -12 &lt;pid&gt; 用于SIGUSR2

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

还将变量 signaL , exitSignal 设为 volatile sig_atomic_t 类型。

为什么volatile

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

为什么sig_atomic_t

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

volatile sig_atomic_t 信号;

【讨论】:

  • 为什么它们有一个 volatile sig_atomic_t 类型?
  • 对 SIGUSR1 使用命令 kill -USR1 &lt;pid&gt;,对 SIGUSR2 使用kill -USR2 。 FTY
猜你喜欢
  • 1970-01-01
  • 2017-06-13
  • 1970-01-01
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多