Có thể tìm ra id quá trình của quá trình đã gây ra một số tín hiệu. Trong kịch bản của tôi, tôi có nhiều con của một tiến trình đang chạy, và tôi muốn biết cái nào trong số họ gửi tín hiệu.Nhận pid của quá trình đã kích hoạt một số tín hiệu
Trả lời
Nó rất đơn giản với python 3.
Sau đây là thử nghiệm với python 3.3.3 (cuối cùng!):
#! /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))
Tôi tin rằng điều đó là không thể - hệ điều hành chỉ không chuyển thông tin này đến quy trình mục tiêu.
Không, không thể, hệ điều hành (có lẽ là * nix) không cung cấp thông tin này. Bạn sẽ cần phải sử dụng một số loại IPC khác để giao tiếp từ các tiến trình con của bạn với cha mẹ. Nếu bạn chưa sử dụng nó, bạn nên kiểm tra các mô-đun subprocess mà làm cho các loại điều dễ dàng.
Ví dụ: nếu bạn thiết lập đường ống từ con của bạn xử lý cho cha mẹ, bạn có thể yêu cầu trẻ viết thông báo cho đường ống khi bạn đã gửi tín hiệu trước đó. Quy trình gốc của bạn có thể sử dụng cuộc gọi select để chờ cho đến khi nhận được tin nhắn từ một trong các trẻ em.
Đây chỉ là một cách bạn có thể tiếp cận vấn đề IPC; bạn cũng có thể làm việc với sockets hoặc mô-đun multiprocessing, trong số các cách tiếp cận khác. Không biết nhiều hơn về những gì bạn đang cố gắng làm, thật khó để cho bạn lời khuyên nào thêm.
cảm ơn ... Tôi đã sử dụng mô-đun subprocess. tôi đang sử dụng wait() để chờ. Nhưng tôi muốn sử dụng signal.pause() mà có thể làm cho quá trình cha mẹ ngủ cho đến khi một trong những đứa trẻ chết. Điều này sẽ tiết kiệm chu kỳ CPU. –
POSIX Linux không cung cấp thông tin này, kiểm tra người đàn ông sigaction (2): http://linux.die.net/man/2/sigaction
Trong C, tôi cố gắng làm cho nó chạy một cách dễ dàng:
#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;
}
trình khá tốt với 3.1 của tôi .6 vanilla kernel và gcc 4.4.5 - nhưng tôi không thể tìm thấy bất kỳ sự hỗ trợ nào cho nó trong python.
Vì vậy, tôi bắt đầu để thử và xây dựng một cái gì đó một mình (nhưng kể từ khi tôi không bao giờ làm C/Python-Tương tác trước đây, nó có thể bằng cách nào đó xoắn lên ...)
tôi ít nhiều giữ gần ví dụ tại http://docs.python.org/extending/extending.html và xây dựng các mô-đun theo 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 để xây dựng các mô-đun:
from distutils.core import setup, Extension
module1 = Extension('sigpid', sources= ['sigpidmodule.c'])
setup (name='SigPid', version='1.0',
description='SigPidingStuff',
ext_modules = [module1])
xây dựng các mô-đun với
python setup.py build
Vì vậy, những gì đang còn mất tích là kịch bản python bằng cách sử dụng mô-đun: 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)
Tất cả mọi thứ hoạt động rất tốt ...lên đến:
python test.py
hoặc như tôi phải thực sự gọi nó là để có được quyền lib:
PYTHONPATH=build/lib.linux-i686-2.6 python test.py
đầu ra:
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
Tôi không biết tại sao tôi có được điều này segfault, và tôi đang hết ý tưởng để sửa nó. Tôi đoán nó phải có một cái gì đó để làm với cách c và python tương tác (Tôi có thể nghĩ ra một số lý do, nhưng đó là tất cả chỉ đoán). Có lẽ ai đó có nhiều kinh nghiệm trong tương tác c-python có thể giúp đỡ ở đây (hoặc ít nhất là giải thích, vấn đề chính xác là gì). Chúng tôi có thể có một cách để giải quyết vấn đề ở đó, ít nhất là trên Linux.
- 1. Xác định pid của quá trình chấm dứt
- 2. Nhận PID của quá trình trong Shell Script
- 3. "Tín hiệu 15 đã nhận được"
- 4. Mở một quá trình với Popen và nhận được PID
- 5. ms C++ nhận pid của quá trình hiện tại
- 6. Làm thế nào tôi có thể nói trong Linux rằng quá trình gửi quá trình của tôi một tín hiệu
- 7. Làm thế nào để một quy trình biết rằng nó đã nhận được tín hiệu
- 8. Gửi tín hiệu đến một quá trình bên trong valgrind?
- 9. Tín hiệu nhận được chương trình SIGABRT
- 10. Khi nào thì một quá trình nhận được SIGABRT (tín hiệu 6)?
- 11. Bỏ qua tín hiệu SIGINT trong quá trình con
- 12. linux: nhận được umask của một quá trình đã chạy?
- 13. Tệp batch của Windows: PID của quá trình cuối cùng?
- 14. Nhận tên tín hiệu từ các số trong Python
- 15. chụp pid quá trình nền đã kết thúc bằng bẫy trong bash
- 16. linux: lập trình có được pid cha của một quá trình khác?
- 17. pid của quá trình thực hiện hiện tại
- 18. PID của quá trình chạy cuối cùng trong Windows
- 19. Tín hiệu pyside quá tải (QComboBox)
- 20. Java: Nhận một quy trình được đưa ra một pid
- 21. Trình nghe tín hiệu - chỉ thực hiện hành động nếu một trường đã thay đổi
- 22. Quá trình đã qua đời
- 23. Chụp PID của một quá trình nền được bắt đầu bởi một Makefile
- 24. Gửi tín hiệu đến quy trình
- 25. Nhận giá trị kích hoạt trình kích hoạt Oracle
- 26. Làm thế nào để gửi tín hiệu SIGINT từ Java sang một quá trình bên ngoài?
- 27. Làm thế nào để bạn xác định PID của phụ huynh của một quá trình
- 28. Tại sao tôi có thể truy cập một đối tượng trong tín hiệu post_save của nó, nhưng không phải khi tôi kích hoạt mã trong tín hiệu đó gọi nó trên một quy trình khác
- 29. chờ đợi quá trình con nhưng nhận được lỗi: 'pid không phải là một đứa trẻ của vỏ này'
- 30. Nhận tín hiệu: Sử dụng chức năng thành viên làm bộ xử lý tín hiệu
Cảm ơn để làm rõ. –