Es posible encontrar la identificación del proceso que ha causado alguna señal. En mi escenario, tengo varios hijos de un proceso en ejecución, y quiero saber cuál de ellos envió la señal.Obtener pid del proceso que ha activado alguna señal
Respuesta
Es muy simple con Python 3.
La siguiente es probado con Python 3.3.3 (por fin!):
#! /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))
Creo que no es posible: el sistema operativo simplemente no pasa esta información al proceso de destino.
No, no es posible, el sistema operativo (presumiblemente a * nix) simplemente no proporciona esta información. Tendrá que usar algún otro tipo de IPC para comunicarse desde los procesos de su hijo al padre. Si aún no lo está utilizando, debería verificar el módulo subprocess, que facilita este tipo de cosas.
Por ejemplo, si configura las canalizaciones de sus procesos secundarios a su padre, puede hacer que el niño escriba un mensaje en el conducto cuando ya habría enviado una señal. El proceso principal puede usar una llamada select para esperar hasta que reciba un mensaje de uno de los hijos.
Esta es solo una forma de abordar el problema del IPC; también puede trabajar con sockets, o el módulo multiprocessing, entre otros enfoques. Sin saber más acerca de lo que intentas hacer, es difícil darte más consejos.
gracias ... Ya estoy usando el módulo de subproceso. Estoy usando esperar() para esperar. Pero quería usar signal.pause() que podría hacer que el proceso padre durmiera hasta que uno de los hijos muera. Esto ahorrará ciclos de CPU. –
POSIX Linux no proporcionar esta información, compruebe sigaction hombre (2): http://linux.die.net/man/2/sigaction
En C, logré hacerlo funcionar fácilmente:
#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;
}
funciona bastante bien con mi 3.1 .6 vainilla kernel y gcc 4.4.5 - pero no pude encontrar ningún soporte para ello en python.
así que empecé a tratar de construir algo por mi cuenta (pero ya que nunca hice C/Python-Interacción antes, es probable que de algún modo torcido ...)
estoy más o menos manteniéndose cerca de el ejemplo de la http://docs.python.org/extending/extending.html y construir el módulo de acuerdo con 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 para la construcción del módulo:
from distutils.core import setup, Extension
module1 = Extension('sigpid', sources= ['sigpidmodule.c'])
setup (name='SigPid', version='1.0',
description='SigPidingStuff',
ext_modules = [module1])
la construcción del módulo con
python setup.py build
Por lo tanto, lo que aún falta es la secuencia de comandos de Python usando el módulo: 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)
Todo funciona muy bien ...hasta:
python test.py
o como tengo que realmente llamarlo para obtener el derecho lib:
PYTHONPATH=build/lib.linux-i686-2.6 python test.py
de salida:
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
No sé por qué me sale esto segfault, y me estoy quedando sin ideas para arreglarlo. Supongo que debe tener algo que ver con cómo c y Python interactúan (puedo pensar en algunas razones, pero todo es solo adivinar). Tal vez alguien con más experiencia en c-python-interaction pueda ayudar aquí (o al menos explicar, cuál es el problema exactamente). Es posible que tengamos una forma de resolver el problema allí, al menos en Linux.
- 1. obtener pid del proceso hijo
- 2. ¿Cómo, en Perl 5, puedo obtener el pid del proceso que me envió una señal?
- 3. Obtener nombre del proceso por PID
- 4. Obtener el nombre del proceso de pid o manejar
- 5. Determine pid de proceso terminado
- 6. señal Django m2m_changed no activado
- 7. ¿Cómo obtener el estado del proceso usando pid?
- 8. ms C++ get pid del proceso actual
- 9. pid del proceso actualmente en ejecución
- 10. ¿Cómo obtener el PID de un proceso dando el nombre del proceso en Mac OS X?
- 11. Obtenga el estado del proceso por pid en Ruby
- 12. Popen obteniendo pid del proceso de nueva ejecución
- 13. cuando se ha activado window.onload
- 14. ¿Cómo un proceso llega a saber que se ha recibido una señal de
- 15. Proceso ha muerto
- 16. ¿La señal KILL sale de un proceso de inmediato?
- 17. Enviar señal al proceso
- 18. Cómo obtener el PID de un proceso en una tubería
- 19. obtener PID de paramiko
- 20. obtener el nombre del proceso desde el proceso id (win32)
- 21. Esperar a que un determinado proceso (conociendo el "PID") final
- 22. Obtener el nombre de PID?
- 23. ¿Cómo obtener el PID infantil en C?
- 24. Conseguir última PID del proceso, en el Makefile
- 25. Archivo por lotes de Windows: ¿PID del último proceso?
- 26. PID del último proceso en ejecución en Windows
- 27. ¿Cómo ver una cola de mensaje de proceso especificada si se conoce el PID del proceso?
- 28. Filtrar por proceso/PID en Wireshark
- 29. ¿Cómo puedo obtener el PID del proceso principal de mi aplicación?
- 30. ¿Cómo obtener el PID del proceso recién iniciado desde un archivo por lotes?
Gracias por la aclaración. –