powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Демон под Linux с возможностью восстановления работы
3 сообщений из 3, страница 1 из 1
Демон под Linux с возможностью восстановления работы
    #38334755
Alex_leshii_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пишу демона под Centos на С++ с контролем работы дочерних процессов.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
#define CHILD_NEED_WORK                 1
#define CHILD_NEED_TERMINATE    2

int ReloadConfig()
{
    ....
    return 0;
}

void DestroyWorkThread()
{...}

int InitWorkThread()
{
     ...
    return 0;
}

int LoadConfig(char* FileName)
{
     ...
    return 0;
}

void SetPidFile(char* Filename)
{
    FILE* f;
    f = fopen(Filename, "w+");
    if (f)
    {
        fprintf(f, "%u\n", getpid());
        fclose(f);
    }
}

int SetFdLimit(int MaxFd)
{
    struct rlimit lim;
    int          status;

    lim.rlim_cur = MaxFd;
    lim.rlim_max = MaxFd;

    status = setrlimit(RLIMIT_NOFILE, &lim);

    return status;
}

//Процесс мониторинга
int MonitorProc()
{
    int      pid;
    int      status;
    int      need_start = 1;
    sigset_t sigset;
    siginfo_t siginfo;
    
    parent_pid = getpid();

    sigemptyset(&sigset);

    sigaddset(&sigset, SIGQUIT);

    sigaddset(&sigset, SIGINT);

    sigaddset(&sigset, SIGTERM);

    sigaddset(&sigset, SIGCHLD);

    sigaddset(&sigset, SIGUSR1);

    sigprocmask(SIG_BLOCK, &sigset, NULL);

    SetPidFile(PID_FILE);
                                                         
    for (;;)
    {
        if (need_start)
        {
            pid = fork();
        }

        need_start = 1;

        if (pid == -1)
        {
            
        }
        else if (!pid) 
        {
            status = WorkProc();

            exit(status);
        }
        else
        {
			//Ожидание сигналов
            sigwaitinfo(&sigset, &siginfo);

            if (siginfo.si_signo == SIGCHLD)
            {
                wait(&status);
                                                                                         
               status = WEXITSTATUS(status);
                                                                                                    
                 if (status == CHILD_NEED_TERMINATE)
                 {
                     Write("[MONITOR] Child stopped");
                     break;
                 }
                 else if (status == CHILD_NEED_WORK)
                 {
                     Write("[MONITOR] Child restart");
                 }
             }
             else if (siginfo.si_signo == SIGUSR1)
             {
                 kill(pid, SIGUSR1); 
                 need_start = 0;
             }
             else if (siginfo.si_signo == 0) 
             {
                need_start = 0;
                continue;
             }
             else
             {
                 Write("[MONITOR] Signal ", strsignal(siginfo.si_signo));
                 kill(pid, SIGTERM);
                 status = 0;
                 break;
             }
         }
     }

     Write("[MONITOR] Stop");
        
     unlink(PID_FILE);

     return status;
}

//Дочерний процесс
int WorkProc()
{
    struct sigaction sigact;
    sigset_t         sigset;
    int             signo;
    int             status;

    sigact.sa_flags = SA_SIGINFO;

    sigact.sa_sigaction = signal_error_for_backtrace;

    sigemptyset(&sigact.sa_mask);

    
    sigaction(SIGFPE, &sigact, 0);
    sigaction(SIGILL, &sigact, 0);
    sigaction(SIGSEGV, &sigact, 0);
    sigaction(SIGBUS, &sigact, 0);

    sigemptyset(&sigset);
    
    sigaddset(&sigset, SIGQUIT);
    
    sigaddset(&sigset, SIGINT);
    
    sigaddset(&sigset, SIGTERM);
    
    sigaddset(&sigset, SIGUSR1);
    sigprocmask(SIG_BLOCK, &sigset, NULL);

    SetFdLimit(FD_LIMIT);
    
    
    status = InitWorkThread();
    
    
    if (!status)
    {
        for (;;)
        {
            sigwait(&sigset, &signo);
        
            if (signo == SIGUSR1)
            {
                status = ReloadConfig();
                if (status)
                {
                    Write("[DAEMON] Reload config failed");
                }
                else
                {
                    Write("[DAEMON] Reload config OK");
                }
            }
            else
            {
                break;
            }
        }
        
        DestroyWorkThread();
    }
    else
    {
        Write("[DAEMON] Create work thread failed");
    }

    Write("[DAEMON] Stopped");
    
    
    return CHILD_NEED_TERMINATE;
}


int main(int argc , char *argv[])
{
     
    if (argc != 2)
    {
        printf("Usage: ./test_daemoun.conf failed!\n");
        return -1;
    }

    status = LoadConfig(argv[1]);
    if (status) 
    {
        printf("Error: Load config failed\n");
        return -1;
    }
    
    if (CheckForAnotherInstance())
    {
	printf("Daemon is already running!\n");
	return 1;
    }
    
    pid = fork();
    if (pid == -1)
    {
        printf("Error: Start Daemon failed (%s)\n", strerror(errno));
        return -1;
    }
    else if (!pid)
    {
        umask(0);
        setsid();
                
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
		//Запуск процесса мониторинга
        status = MonitorProc();
        return status;
    }
    else
    {
        return 0;
    }
    return 0;
}



Имеется монитор - основной процесс, и дочерний процесс, в котором выполняются основная обработка. Проблема состоит в том, что при завершении дочернего процесса сигнал SIGCHLD о его завершении родительский процесс не получает.
При этом после отправки из консоли kill -s SIGTERM родительский процесс отлавливает этот сигнал. А самое странное, что при подключении к родительскому процессу с помощью strace все работает как надо - сигнал приходит в родительский процесс.
Читал про функцию waitpid - для отлавливания этого типа сигналов - но хотелось бы более универсального решения.
Подскажите, пожалуйста, что я делаю не так.
...
Рейтинг: 0 / 0
Демон под Linux с возможностью восстановления работы
    #38334828
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_leshii_,

Так а что ж вы хотели, когда у вас этот сигнал в коде явно блокируется:
Код: plaintext
1.
2.
3.
    sigaddset(&sigset, SIGCHLD);
    ...
    sigprocmask(SIG_BLOCK, &sigset, NULL);
...
Рейтинг: 0 / 0
Демон под Linux с возможностью восстановления работы
    #38335039
Alex_leshii_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovsky,

Судя по докам, блокировка сигналов должна вызываться перед функцией fork. А затем разблокировка происходит при вызове sigwaitinfo.
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Демон под Linux с возможностью восстановления работы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]