2011-02-11 16 views
6

ट्रिगर किया है क्या प्रक्रिया के प्रक्रिया आईडी को खोजना संभव है जिसके कारण कुछ सिग्नल हैं। मेरे परिदृश्य में, मेरे पास एक प्रक्रिया के कई बच्चे चल रहे हैं, और मैं जानना चाहता हूं कि उनमें से कौन सा सिग्नल भेजता है।प्रक्रिया के ढक्कन को प्राप्त करें जिसने कुछ सिग्नल

उत्तर

6

यह है अजगर 3.

साथ बहुत ही सरल निम्नलिखित अजगर 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)) 
-3

मुझे विश्वास है कि यह संभव नहीं है - ओएस बस इस जानकारी को लक्ष्य प्रक्रिया में पास नहीं करता है।

+0

स्पष्ट करने के लिए धन्यवाद। –

-2

नहीं, यह संभव नहीं है, ओएस (संभवतः एक * निक्स) बस यह जानकारी प्रदान नहीं करता है। आपको अपने बच्चे की प्रक्रियाओं से माता-पिता को संवाद करने के लिए किसी अन्य प्रकार के आईपीसी का उपयोग करने की आवश्यकता होगी। यदि आप पहले से इसका उपयोग नहीं कर रहे हैं तो आपको subprocess मॉड्यूल देखना चाहिए जो इन प्रकार की चीजों को आसान बनाता है।

उदाहरण के लिए, यदि आप अपने बच्चे की प्रक्रियाओं से अपने माता-पिता को पाइप सेट करते हैं, तो आप बच्चे को पाइप पर एक संदेश लिखने के लिए प्राप्त कर सकते हैं जब आप पहले सिग्नल भेज चुके थे। आपकी मूल प्रक्रिया select कॉल का उपयोग तब तक प्रतीक्षा कर सकती है जब तक कि इसे किसी एक बच्चे से संदेश प्राप्त न हो जाए।

यह केवल एक ही तरीका है जिससे आप आईपीसी समस्या से संपर्क कर सकते हैं; आप अन्य दृष्टिकोणों के साथ sockets, या multiprocessing मॉड्यूल के साथ भी काम कर सकते हैं। आप जो करने की कोशिश कर रहे हैं उसके बारे में अधिक जानने के बिना आपको और सलाह देना मुश्किल है।

+0

धन्यवाद ... मैं पहले से ही सबप्रोसेस मॉड्यूल का उपयोग कर रहा हूं। मैं प्रतीक्षा करने के लिए प्रतीक्षा() का उपयोग कर रहा हूँ। लेकिन मैं सिग्नल.pause() का उपयोग करना चाहता था जो माता-पिता की मृत्यु होने तक माता-पिता की प्रक्रिया को नींद कर सकता है। यह सीपीयू चक्र बचाएगा। –

5

POSIX लिनक्स यह जानकारी प्रदान करता है, आदमी sigaction (2) की जाँच करें: http://linux.die.net/man/2/sigaction

सी में, मैं इसे आसानी से चल पाने में कामयाब रहे:

#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 वेनिला कर्नेल और जीसीसी 4.4.5 - लेकिन मुझे पाइथन में इसके लिए कोई समर्थन नहीं मिला।

तो मैं कोशिश करना और अपने दम पर कुछ निर्माण (लेकिन जब से मैं कभी नहीं सी/अजगर-इंटरैक्शन से पहले किया था, यह शायद किसी भी तरह ऊपर मुड़ रही है ...)

मैं और अधिक या कम के करीब रखने कर रहा हूँ शुरू कर दिया 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 

साथ मॉड्यूल का निर्माण तो, क्या अभी भी लापता है मॉड्यूल का उपयोग कर अजगर स्क्रिप्ट है: 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, और मैं इसे ठीक करने के लिए विचारों से बाहर चला रहा हूँ। मुझे लगता है कि सी और पायथन कैसे बातचीत करते हैं इसके साथ कुछ करना होगा (मैं कुछ कारणों से सोच सकता हूं, लेकिन यह केवल अनुमान लगा रहा है)। हो सकता है कि सी-पायथन-इंटरैक्शन में अधिक अनुभव वाला कोई व्यक्ति यहां मदद कर सके (या कम से कम समझाएं, वास्तव में समस्या क्या है)। कम से कम लिनक्स पर, समस्या को हल करने का हमारा तरीका हो सकता है।

संबंधित मुद्दे