Статус Systemd говорит, что демон активен (запущен), но демон не выполняется и создает повторяющиеся процессы

#c #raspberry-pi #fork #raspbian #systemd

#c #raspberry-pi #fork #raspbian #systemd

Вопрос:

Ниже приведен код для демона (на C).

     int main(void) {
    
    /* Our process ID and Session ID */
    pid_t pid2;
    
    /* The Big Loop */
    while (1) {
        time_t now;
        time(amp;now);
        struct tm *local = localtime(amp;now);
        int hour = local->tm_hour;
        int min = local->tm_min;
        int earliest_time = 0; //8AM earliest a workout will be developed
        int latest_time = 24; //5PM latest a workout will be developed
        int min_interval = 20; //minimum interval of a workout
        int max_interval = 30; //maximum interval of a workout

        //If it's in between these hours of the day...
        if (hour >= earliest_time amp;amp; hour < latest_time){

            int rand_interval = (rand() % (max_interval   1 - min_interval))   min_interval;

            pid2 = fork();
            if (pid2 == 0){
                execlp("./workout_SMS.py","./workout_SMS.py",NULL);
            }
            
            waitpid(pid2,0,0);
            //kill(pid2,SIGTERM);
            sleep(rand_interval);
        }

        else{
        sleep(60); /* wait 30 seconds */
        }
    }
exit(EXIT_SUCCESS);
 

}

Я хочу, чтобы этот демон запускался при загрузке с использованием Systemd. В соответствии с руководством Systemd и другими онлайн-источниками я настроил файл daemon.service, как показано ниже.

 [Unit]
Description=workout-daemon startup service
[Service]
User=pi
Type=simple
ExecStart=/home/pi/python/twilio/workout_SMS/workout-daemon
Restart=on-failure

[Install]
WantedBy=multi-user.target
 

Ниже приведен статус Systemd демона. Как показано, статус говорит, что он «активен (запущен)» и со временем продолжает создавать новые повторяющиеся процессы. Желаемое поведение заключается в том, что он запускает только один процесс и не создает дубликатов.

 ● workout.service - workout-daemon startup service file for text message workouts
   Loaded: loaded (/etc/systemd/system/workout.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2020-12-29 03:15:35 PST; 1min 41s ago
 Main PID: 22363 (workout-daemon)
    Tasks: 5 (limit: 881)
   CGroup: /system.slice/workout.service
           ├─22363 /home/pi/python/twilio/workout_SMS/workout-daemon
           ├─22364 /home/pi/python/twilio/workout_SMS/workout-daemon
           ├─22409 /home/pi/python/twilio/workout_SMS/workout-daemon
           ├─22493 /home/pi/python/twilio/workout_SMS/workout-daemon
           └─22525 /home/pi/python/twilio/workout_SMS/workout-daemon
 

Ожидаемая операция заключается в том, что скрипт python отправляет текстовое сообщение на мой телефон через определенные промежутки времени. Демон будет функционировать должным образом при запуске непосредственно из рабочего каталога, но он не работает должным образом, когда я использую «sudo systemctl daemon-reload» -> «sudo systemctl включить workout.service» -> «sudo systemctl запустить workout.service».

Есть ли что-то, чего мне не хватает в моей конфигурации Systemd?

Комментарии:

1.Что вы подразумеваете под «не функционирует должным образом»? Что он должен делать и что он на самом деле делает? Вы пробовали сделать self fork опцией (например, если программе присвоен a -f ). Затем systemd управляйте им нормально (т. Е. Под systemd , Программа этого не fork делает). [AFAICT] Большинство служб не выполняют Type=forking

2. Я отредактировал код daemon C в исходном вопросе, чтобы включить код в цикл while (1). Я удалил fork() в основной части функции int и изменил тип на Type=simple в файле конфигурации .service . Теперь статус Systemd говорит, что он неактивен (мертв) и «code» work out.service: основной процесс завершен, code = убит, status = 15 / TERM’code’

3. systemd обнаруживает и жалуется kill(pid2,SIGTERM); на то, что вы делаете. В этом нет необходимости, потому что после waitpid того, как , pid2 исчезнет . Итак, удалите kill . Примечание: Спорный вопрос, но, по моему мнению, причина , по которой он жаловался, заключается в том, что вы не делали: if (pid2 != 0) kill(pid2,SIGTERM); итак, вы делали kill(0,SIGTERM); , что означает: Если pid равно 0, то sig отправляется каждому процессу в группе процессов вызывающего процесса. Следовательно, ваш демон убивал себя

4. Удаление команды kill(pid2, SIGTERM) теперь позволяет демону быть активным (запущенным), но я думаю, что при его удалении каждый раз, когда повторяется оператор wait(1), создается новый экземпляр /home/pi/python/twilio/workout_SMS/workout-daemon иони начинают накапливаться в фоновом режиме по 1 за раз. И, несмотря на то, что он активен и создает новый процесс, мой телефон не получает текстовых сообщений ни от одного из процессов. Есть мысли о том, почему новый экземпляр демона будет создаваться после каждой итерации цикла ожидания (1)? И почему он полностью игнорирует скрипт python?

5. Вы делаете chdir("/"); . Позже вы делаете execlp("./workout_SMS.py",...); то, что произойдет, если execlp сбой (т. Е. Как обращаться? делать printf и затем exit(9) )?