Czy jest możliwe, aby dowiedzieć się id procesu, który spowodował jakiś sygnał. W moim scenariuszu mam wiele procesów potomnych, a ja chcę wiedzieć, który z nich wysłał sygnał.Pid procesu, który uruchomił jakiś sygnał
Odpowiedz
To bardzo proste z Pythona 3.
Poniżej jest testowany z Pythona 3.3.3 (wreszcie!):
#! /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))
Uważam, że nie jest to możliwe - system operacyjny po prostu nie przekazuje tych informacji do procesu docelowego.
Nie, to niemożliwe, system operacyjny (prawdopodobnie * nix) po prostu nie podaje tych informacji. Będziesz musiał użyć innego rodzaju IPC do komunikacji z procesów potomnych do rodzica. Jeśli jeszcze go nie używasz, powinieneś sprawdzić moduł subprocess, który ułatwia tego typu rzeczy.
Na przykład, jeśli skonfigurujesz potoki z procesów potomnych do rodzica, możesz poprosić dziecko, aby napisało wiadomość do potoku, gdy wcześniej wysłałeś sygnał. Twój proces nadrzędny może używać wywołania select, aby czekać, aż otrzyma wiadomość od jednego z dzieci.
To tylko jeden ze sposobów podejścia do problemu IPC; można również pracować z modułem sockets lub multiprocessing, wśród innych podejść. Nie wiedząc więcej o tym, co próbujesz zrobić, trudno jest ci udzielić więcej porad.
dzięki ... Korzystam już z modułu podprocesu. używam wait(), aby czekać. Ale chciałem użyć signal.pause(), która mogłaby sprawić, że proces rodzicielski spał, dopóki jedno z dzieci nie umrze. Pozwoli to zaoszczędzić cykle procesora. –
POSIX Linux ma dostarczania tych informacji, sprawdź sigaction Man (2): http://linux.die.net/man/2/sigaction
w C, udało mi się dostać to działa w prosty sposób:
#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;
}
działa całkiem dobrze z moim 3,1 .6 jądro wanilii i gcc 4.4.5 - ale nie mogłem znaleźć żadnego wsparcia dla niego w pythonie.
więc zacząłem próbować zbudować coś na własną rękę (ale ponieważ nigdy nie zrobiłem C/python-Interaction wcześniej, to pewnie jakoś skręcone w górę ...)
jestem mniej lub bardziej trzymając się blisko Podany przykład http://docs.python.org/extending/extending.html i budowy modułu według 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 do budowy modułu:
from distutils.core import setup, Extension
module1 = Extension('sigpid', sources= ['sigpidmodule.c'])
setup (name='SigPid', version='1.0',
description='SigPidingStuff',
ext_modules = [module1])
budowę modułu z
python setup.py build
Tak, to wciąż brakuje skrypt python za pomocą modułu: 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)
Wszystko działa bardzo dobrze ...do:
python test.py
lub jak mam właściwie nazwać to, aby uzyskać prawo lib:
PYTHONPATH=build/lib.linux-i686-2.6 python test.py
wyjściowa:
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
nie wiem dlaczego mam to segfault i brakuje mi pomysłów, aby to naprawić. Myślę, że to musi mieć coś wspólnego z interakcją c i Pythona (mogę myśleć o pewnych przyczynach, ale to wszystko tylko zgadywanie). Może ktoś z większym doświadczeniem w interakcji c-python może pomóc (lub przynajmniej wyjaśnić, jaki jest dokładnie problem). Możemy mieć sposób na rozwiązanie tego problemu, przynajmniej na Linuksie.
- 1. Określanie pid zakończonego procesu
- 2. pid aktualnie wykonywanego procesu
- 3. Który użytkownik uruchomił instancję EC2?
- 4. Wyślij sygnał do procesu
- 5. Jak uzyskać identyfikator PID procesu, który jest podłączony do innego procesu w Bash?
- 6. linux: programowo uzyskasz pid rodzicielski innego procesu?
- 7. Schowek znajdź pojemnik według pid procesu wewnętrznego
- 8. PID procesu gnome-terminal w tle
- 9. Pierwsze PID procesu utworzonego w C#
- 10. Czy jest jakiś sposób poznania pid z uruchomionego programu?
- 11. Jak uzyskać identyfikator PID procesu, podając nazwę procesu w systemie Mac OS X?
- 12. Jak uzyskać pid z aktualnie debugowanego procesu w gdb?
- 13. Jak zdobyć PID i nr portu dla procesu Jenkinsa
- 14. Jak znaleźć nazwę aplikacji przez PID (identyfikator procesu)
- 15. Jak uzyskać PID procesu właśnie rozpoczęty z wewnątrz pliku wsadowego?
- 16. Czy sygnał ZABISKU natychmiast opuszcza proces?
- 17. Określanie, który szablon procesu TFS jest używany
- 18. Jak sprawdzić, który port używa procesu?
- 19. Czy istnieje sposób, aby dowiedzieć się, który użytkownik jest właścicielem procesu z procesu task_struct procesu?
- 20. Znajdź pid Visual Studio, który debuguje mój proces
- 21. Biorąc pod uwagę PID dziecka, jak uzyskać rodzic PID
- 22. Jak monitorować zewnętrzny proces zdarzeń za pomocą jego PID w C?
- 23. Bash: Uzyskiwanie PID z demonizowanej sesji screenowej
- 24. W jaki sposób _do_fork() zwraca dwa różne PID (jeden dla procesu nadrzędnego i jeden dla procesu potomnego)
- 25. Jak właściwie czekać na zakończenie wydarzenia/procesu, który nie jest rodzicem?
- 26. Jak parsować/proc/pid/cmdline
- 27. Jak mogę uzyskać stdin procesu przez identyfikator procesu?
- 28. Jak sprawdzić, czy launchd uruchomił skrypt?
- 29. Czy ktoś uruchomił testy wydajności porównujące LINQ
- 30. sygnał Uchwyt z sigaction
Dzięki za wyjaśnienie. –