Kombinacja boost::child i biblioteki Poco

0

Hej,
Napotkałem na bardzo powazny problem.
Mam zaimplementowany prosty serwer Poco i chcę w jednym z żądań uruchomić aplikacje - możliwe są 2 tryby -
a) praca w tle - wynik nie jest wyświetlany
b) praca w trakcie wykonywania żądania - wynik jest wyświetlany

Doczytałem, że boost::child nie jest thread safe i to mnie powiem szczerze przeraziło - chociaż do tej pory tryb b) działał bez zarzutu.

  1. Co powinien zrobić żeby to poprawić/ czego użyć?

  2. W trybie a) procesy nie są zakańczane - funkcjonują jako zombie, więc myślałem nad ograniczeniem do 1 aplikacji na raz ale to tez średnie rozwiązanie

1

Co to znaczy w Twoim kontekście "nie jest thread safe" i gdzie to wyczytałeś?
Musiałbym w źródła boosta spojrzeć głębiej, ale nie wiem czy to nie jest pewna historyczna zaszłość:
http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them
Bo wiem, że na 100% używa forka.

EDIT: o tym 3cim pkcie mówisz? https://www.boost.org/doc/libs/1_64_0/doc/html/boost/process/child.html
No wciąż, tak długo jak nie dzielisz boostowego handle'a na dziko pomiędzy wątkami i zamykasz co masz zamykać (czy POSIXowym FD_CLOEXEC czy close_fds z boosta) raczej nie wpadniesz w problemy, jeśli Twoja appka nie robi cudów z IPC. Jeśli robi - to już musisz indywidualnie rozpatrywać.

0

Co to znaczy w Twoim kontekście "nie jest thread safe" i gdzie to wyczytałeś?

http://www.highscore.de/boost/process0.5/boost_process/faq.html#boost_process.faq.is_boost_process_thread_safe_

Sęk w tym, że właśnie jak na razie nie napotkałem problemu w trybie "pracy w trakcie wykonywania żądania".
Problem natomiast mam z tryb pracy w tle, ponieważ zostają procesy zombie - gdy dopisałem SIGCHLD handler było ok ale nie, gdy pojawiły się kilka procesy - jeden zabijał pozostałe.
Może to jest właśnie problematyczne również z trybem b).

1

Pokaż tego handlera

0
void handleSignalChild(int signum)
{
    for (pid_t pid = waitpid(-1, NULL, WNOHANG);
        pid != 0 && pid != -1;
        pid = waitpid(-1, NULL, WNOHANG))
    {
        std::cout << "zombie process detected (pid == " << std::dec << pid << ")." << std::endl;
    }
}

int main(int argc, char* argv[])
{
#ifdef OS_LINUX
    signal(SIGCHLD, handleSignalChild);
#endif

#edit fragment kodu tworzący child process:

               boost::process::child childProcess
                (
                    "sleep 10",
                    boost::process::std_in.close(),
                    boost::process::std_out.close()
                );
                childProcess.detach();
1

Jesteś w stanie zebrać status z tego waitpida i go wyświetilć? Bo dziwne, że jeden pozostałe ubija. No i pytanie: one nie potrzebują "controlling terminal"?
EDIT: i nie polecam w handlerze pisać po strumieniach, jak chcesz wyświetlić to ::write do STDOUT_FILENO.

0

Hm, teraz to już nie wiem, czy w końcu dobrze działa, czy nie.
Chyba wszystko ok jest teraz...
Status zawsze zwraca 0.

Potestuje to jeszcze...

No i pytanie: one nie potrzebują "controlling terminal"?

Nie.

#edit
Wygląda na to, że sygnał jest obsługiwany z pewnym opóźnieniem, dlatego też widziałem znikające X procesów na raz - wydłużyłem czas między procesami i jest ok.
W sumie to robi nawet handler, który dopisałem...

1 użytkowników online, w tym zalogowanych: 0, gości: 1