E 'possibile scoprire l'id del processo del processo che ha causato qualche segnale. Nel mio scenario, ho più figli di un processo in esecuzione, e voglio sapere quale di loro ha inviato il segnale.Ottenere PID del processo che ha innescato qualche segnale
risposta
E 'molto semplice, con pitone 3.
effettuano i seguenti controlli con Python 3.3.3 (finalmente!):
#! /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))
io credo che non sia possibile - il sistema operativo semplicemente non passa queste informazioni al processo di destinazione.
No, non è possibile, il sistema operativo (presumibilmente un * nix) semplicemente non fornisce questa informazione. Dovrai utilizzare un altro tipo di IPC per comunicare dai processi figli al genitore. Se non lo stai già utilizzando, dovresti controllare il modulo subprocess che facilita questo tipo di operazioni.
Ad esempio, se si imposta tubi dei tuoi processi figlio al genitore, è possibile ottenere il bambino a scrivere un messaggio al tubo quando si sarebbe in precedenza stato inviato un segnale. La tua procedura padre può utilizzare una chiamata select per attendere finché non riceve un messaggio da uno dei bambini.
Questo è solo un modo per affrontare il problema IPC; si può anche lavorare con sockets, oppure il modulo multiprocessing, tra gli altri approcci. Senza saperne di più su ciò che stai cercando di fare, è difficile dare ulteriori consigli.
grazie ... Sto già usando il modulo subprocess. sto usando wait() per aspettare. Ma volevo usare signal.pause() che potesse far dormire il genitore fino a quando uno dei bambini muore. Ciò salverà i cicli della CPU. –
POSIX Linux non fornire queste informazioni, controllare l'uomo sigaction (2): http://linux.die.net/man/2/sigaction
In C, sono riuscito a farlo funzionare facilmente:
#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;
}
funziona abbastanza bene con la mia 3.1 .6 kernel di vaniglia e gcc 4.4.5 - ma non ho trovato alcun supporto per questo in python.
così ho iniziato a cercare di costruire qualcosa per conto mio (ma dato che non ho mai fatto C/Python-interazione prima, probabilmente in qualche modo torto ...)
sto più o meno tenere vicino alla nell'esempio a http://docs.python.org/extending/extending.html e ricostruire il modulo secondo 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 per generare il modulo:
from distutils.core import setup, Extension
module1 = Extension('sigpid', sources= ['sigpidmodule.c'])
setup (name='SigPid', version='1.0',
description='SigPidingStuff',
ext_modules = [module1])
costruzione del modulo con
python setup.py build
Quindi, ciò che ancora manca è lo script Python usando il modulo: 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)
Tutto funziona molto bene ...fino a:
python test.py
o come devo chiamare in realtà per ottenere la giusta lib:
PYTHONPATH=build/lib.linux-i686-2.6 python test.py
uscita:
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
Non so perché ho questo segfault, e sono a corto di idee per sistemarlo. Immagino che debba avere qualcosa a che fare con il modo in cui c e python interagiscono (posso pensare ad alcune ragioni, ma è tutto solo a indovinare). Forse qualcuno con più esperienza nell'interazione c-python può aiutare qui (o almeno spiegare, qual è il problema esattamente). Potremmo avere un modo per risolvere il problema lì, almeno su Linux.
- 1. Determinare il pid del processo terminato
- 2. ottenendo pid del processo figlio
- 3. Come ottenere i dettagli del processo dal suo pid
- 4. Ottenere il PID del processo in Shell Script
- 5. Ottenere ultimo processo PID in Makefile
- 6. Ottieni il nome del processo tramite PID
- 7. Come ottenere il PID di un processo che viene convogliato su un altro processo in Bash?
- 8. Trova PID del processo che utilizzano una porta su Windows
- 9. pid del processo attualmente in esecuzione
- 10. Un segnale KILL chiude immediatamente un processo?
- 11. Problemi durante l'invio del segnale al processo figlio in C
- 12. L'apertura di un processo con Popen e ottenere il PID
- 13. Ottenere un pid di un processo creato in C#
- 14. Ottieni il nome del processo da pid o handle
- 15. Come ottenere il PID del rake corrente?
- 16. Invia segnale a processo
- 17. Nome processo dal suo pid in linux
- 18. Ottieni lo stato del processo da pid in Ruby
- 19. risparmio PID del processo generato all'interno di un Makefile
- 20. Come ottenere PID e Port # per un processo Jenkins
- 21. Come fa un processo a sapere che ha ricevuto un segnale
- 22. Come ottenere il PID figlio in C?
- 23. Come ottenere il PID del processo specificando il nome del processo e memorizzandolo in una variabile da utilizzare ulteriormente?
- 24. PID dell'ultimo processo in esecuzione in Windows
- 25. Trova il pid di Visual Studio che esegue il debug del mio processo
- 26. File batch di Windows: PID dell'ultimo processo?
- 27. Python: processo di demonizzazione con file PID
- 28. Ottenere la potenza del segnale bluetooth
- 29. Vai: Ottieni l'origine del segnale
- 30. Ottenere l'ID del processo dell'applicazione excel
Grazie per il chiarimento. –