Получить pid процесса, который вызвал некоторый сигнал

Возможно ли узнать идентификатор процесса, вызвавшего некоторый сигнал. В моем сценарии у меня несколько дочерних процессов процесса, и я хочу знать, какой из них отправил сигнал.

  • это атомарное присвоение переменной python?
  • Проблема Threading and Signals в PyQt
  • Как я могу отправить сигнал из программы python?
  • Как предотвратить конфликты приборов с конфликтом с сигнальным кодом django post_save?
  • Как мне высмеять обработчик сигнала django?
  • Почему post_save создается дважды во время сохранения модели Django?
  • Django: сигнал, когда пользователь входит в систему?
  • сельдерей пытается остановить работника, повысив SystemExit в сигнале task_postrun, но всегда зависает, и основной процесс никогда не выходит
  • 4 Solutions collect form web for “Получить pid процесса, который вызвал некоторый сигнал”

    Это (наконец!) Очень просто с python 3.

    Следующее тестируется с помощью python 3.3.3:

    #! /usr/bin/python3 import signal import time, os def callme(num, frame): pass # register the callback: signal.signal(signal.SIGUSR1, callme) print("py: Hi, I'm %d, talk to me with 'kill -SIGUSR1 %d'" % (os.getpid(),os.getpid())) # wait for signal info: while True: siginfo = signal.sigwaitinfo({signal.SIGUSR1}) print("py: got %d from %d by user %d\n" % (siginfo.si_signo, siginfo.si_pid, siginfo.si_uid)) 

    POSIX Linux предоставляет эту информацию, проверьте man sigaction (2): http://linux.die.net/man/2/sigaction

    В C мне удалось легко запустить его:

     #include <stdio.h> #include <unistd.h> #include <string.h> #include <signal.h> static void my_handler(int signum, siginfo_t *siginfo, void *context) { printf("Got signal '%d' from process '%d' of user '%d'\n", signum, siginfo->si_pid, siginfo->si_uid); } int main(void) { struct sigaction act; memset(&act, '\0', sizeof(act)); act.sa_sigaction = &my_handler; act.sa_flags = SA_SIGINFO; sigaction(SIGUSR1, &act, NULL); printf("Hi, my pid is %d\ntalk to me with 'kill -SIGUSR1 %d'\n", getpid(), getpid()); while(1) sleep(1000); return 0; } в #include <stdio.h> #include <unistd.h> #include <string.h> #include <signal.h> static void my_handler(int signum, siginfo_t *siginfo, void *context) { printf("Got signal '%d' from process '%d' of user '%d'\n", signum, siginfo->si_pid, siginfo->si_uid); } int main(void) { struct sigaction act; memset(&act, '\0', sizeof(act)); act.sa_sigaction = &my_handler; act.sa_flags = SA_SIGINFO; sigaction(SIGUSR1, &act, NULL); printf("Hi, my pid is %d\ntalk to me with 'kill -SIGUSR1 %d'\n", getpid(), getpid()); while(1) sleep(1000); return 0; } 

    Хорошо работает с моим ядро ​​3.1.6 vanilla и gcc 4.4.5, но я не смог найти поддержки в python.

    Поэтому я начал пытаться создавать что-то самостоятельно (но так как раньше я никогда не занимался C / Python-Interaction, это, вероятно, как-то скручено …)

    Я более или менее придерживаюсь примера на http://docs.python.org/extending/extending.html и строю модуль согласно http://docs.python.org/extending/building.html#building

    sigpidmodule.c

     #include <Python.h> #include <signal.h> static PyObject *callback = NULL; static void direct_handler(int signum, siginfo_t *siginfo, void *context) { int pid = (int) siginfo->si_pid; printf("c: Signal reached c handler: signum=%d, pid=%d, handler=%p\n", signum, pid, callback); if ( callback != NULL ) { PyObject *arglist = Py_BuildValue("(i,i)", signum, pid); printf("c: calling python callback\n"); PyObject *result = PyObject_CallObject(callback, arglist); // decrease reference counter Py_DECREF(arglist); Py_DECREF(result); } } static PyObject *sigpid_register(PyObject *self, PyObject *args) { PyObject *result = NULL; PyObject *temp; if ( PyArg_ParseTuple(args, "O:set_callback", &temp) ) { if ( !PyCallable_Check(temp) ) { PyErr_SetString(PyExc_TypeError, "parameter must be callable"); return NULL; } } Py_XINCREF(temp); // inc refcount on new callback Py_XDECREF(callback); // dec refcount on old callback callback = temp; // replace old callback with new printf("c: callback now: %p\n", (void *) callback); // return None Py_RETURN_NONE; } static PyObject *sigpid_ping(PyObject *self, PyObject *args) { if ( callback != NULL ) { PyObject *arglist = Py_BuildValue("(i,i)", 42, 23); printf("c: calling callback...\n"); PyObject *result = PyObject_CallObject(callback, arglist); // decrease ref counters Py_DECREF(arglist); Py_DECREF(result); } // return None: Py_RETURN_NONE; } static PyMethodDef SigPidMethods[] = { {"register", sigpid_register, METH_VARARGS, "Register callback for SIGUSR1"}, {"ping", sigpid_ping, METH_VARARGS, "Test if callback is working"}, {NULL, NULL, 0, NULL}, }; PyMODINIT_FUNC initsigpid(void) { // initialize module: (void) Py_InitModule("sigpid", SigPidMethods); // set sighandler: struct sigaction act; memset(&act, '\0', sizeof(act)); act.sa_sigaction = &direct_handler; act.sa_flags = SA_SIGINFO; sigaction(SIGUSR1, &act, NULL); } 

    setup.py для создания модуля:

     from distutils.core import setup, Extension module1 = Extension('sigpid', sources= ['sigpidmodule.c']) setup (name='SigPid', version='1.0', description='SigPidingStuff', ext_modules = [module1]) 

    построение модуля с помощью

     python setup.py build 

    Итак, что еще не хватает, это скрипт python с помощью модуля: test.py

     import sigpid import time, os def callme(num, pid): ''' Callback function to be called from c module ''' print "py: got %d from %d\n" % (num, pid) # register the callback: sigpid.register(callme) print "py: Hi, I'm %d, talk to me with 'kill -SIGUSR1 %d'" %(os.getpid(),os.getpid()) # wait for signal while doing nothing: while True: time.sleep(1) 

    Все работает очень хорошо … до:

     python test.py 

    или, как я должен на самом деле назвать его, чтобы получить право lib:

     PYTHONPATH=build/lib.linux-i686-2.6 python test.py 

    вывод:

     c: callback now: 0xb744f534 py: Hi, I'm 2255, talk to me with 'kill -SIGUSR1 2255' (from other term: kill -SIGUSR1 2255) c: Signal reached c handler: signum=10, pid=2948, handler=0xb744f534 c: calling python callback Segmentation fault 

    Я не знаю, почему я получаю этот segfault, и у меня заканчиваются идеи, чтобы исправить это. Я предполагаю, что это должно иметь какое-то отношение к тому, как взаимодействуют c и python (я могу думать о некоторых причинах, но все это только гадание). Может быть, кто-то, у кого больше опыта в c-python-взаимодействии, может помочь здесь (или, по крайней мере, объяснить, в чем проблема). У нас может быть способ решить проблему там, по крайней мере, на Linux.

    Нет, это невозможно, ОС (предположительно, * nix) просто не предоставляет эту информацию. Вам нужно будет использовать какой-то другой IPC для связи с дочерними процессами с родителем. Если вы еще не используете его, вы должны проверить модуль подпроцесса, который упрощает эти вещи.

    Например, если вы настроите трубы из дочерних процессов на родителя, вы можете заставить ребенка написать сообщение в трубку, когда вы ранее отправляли сигнал. Ваш родительский процесс может использовать вызов select, чтобы подождать, пока он не получит сообщение от одного из детей.

    Это только один из способов, которым вы можете приблизиться к проблеме IPC; вы также можете работать с сокетами или модулем многопроцессорности среди других подходов. Не зная больше о том, что вы пытаетесь сделать, сложно дать вам больше советов.

    Я считаю, что это невозможно – ОС просто не передает эту информацию целевому процессу.

    Python - лучший язык программирования в мире.