我刚刚开始在django项目中实现信号监听器.虽然我明白它们是什么以及如何使用它们.我很难搞清楚应该放在哪里.来自django网站的文档有这样的说法:
您可以将信号处理和注册码放在任何您喜欢的地方.但是,您需要确保早期导入模块,以便在需要发送任何信号之前注册信号处理.这使您的应用程序的models.py成为放置信号处理程序注册的好地方.
虽然这是一个很好的建议,但在我的models.py中使用非模型类或方法只会让我误以为然.
那么,存储和注册信号处理程序的最佳实践/规则是什么?
而已.只是想知道SIGSTOP和SIGTSTP之间的区别.
我想写一个信号处理程序来捕获SIGSEGV.我使用保护内存块进行读写
char *buffer;
char *p;
char a;
int pagesize = 4096;
mprotect(buffer,pagesize,PROT_NONE)
Run Code Online (Sandbox Code Playgroud)
这可以保护从缓冲区开始的内存大小字节的内存,防止任何读取或写入.
其次,我尝试读取内存:
p = buffer;
a = *p
Run Code Online (Sandbox Code Playgroud)
这将生成一个SIGSEGV,我的处理程序将被调用.到现在为止还挺好.我的问题是,一旦调用处理程序,我想通过这样做来改变内存的访问写入
mprotect(buffer,pagesize,PROT_READ);
Run Code Online (Sandbox Code Playgroud)
并继续正常运行我的代码.我不想退出该功能.在将来写入相同内存时,我想再次捕获信号并修改写入权限,然后记录该事件.
这是代码:
#include <signal.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
char *buffer;
int flag=0;
static void handler(int sig, siginfo_t *si, void *unused)
{
printf("Got SIGSEGV at address: 0x%lx\n",(long) si->si_addr);
printf("Implements the handler only\n");
flag=1;
//exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{ …Run Code Online (Sandbox Code Playgroud) 我可以向信号处理程序提供/传递任何参数吗?
/* Signal handling */
struct sigaction act;
act.sa_handler = signal_handler;
/* some more settings */
Run Code Online (Sandbox Code Playgroud)
现在,处理程序看起来像这样:
void signal_handler(int signo) {
/* some code */
}
Run Code Online (Sandbox Code Playgroud)
如果我想做一些特殊的事情,即删除临时文件,我可以将这些文件作为参数提供给这个处理程序吗?
编辑0:谢谢你的回答.我们通常避免/不鼓励使用全局变量.在这种情况下,如果你有一个庞大的程序,在不同的地方可能会出现问题,你可能需要进行大量的清理工作.为什么API以这种方式设计?
我想知道异步信号处理程序的执行在Linux上是如何工作的.首先,我不清楚哪个线程执行信号处理程序.其次,我想知道使线程执行信号处理程序所遵循的步骤.
关于第一件事,我读了两个看似矛盾的不同解释:
Linux内核,由Andries Brouwer撰写,§5.2"接收信号"状态:
当信号到达时,进程被中断,保存当前寄存器,并调用信号处理程序.当信号处理程序返回时,中断的活动继续.
在StackOverflow上的问题"处理异步信号在多线程程序"使我认为,Linux的行为是像SCO Unix的:
当信号传递给进程时,如果它被捕获,它将由满足以下任一条件的一个且只有一个线程处理:
在sigwait(2)系统调用中阻塞的线程,其参数确实包括捕获信号的类型.
一个线程,其信号掩码不包括捕获信号的类型.
其他考虑因素
- 在sigwait(2)中被阻塞的线程优先于不阻塞信号类型的线程.
- 如果多个线程满足这些要求(可能两个线程正在调用sigwait(2)),那么将选择其中一个.应用程序无法预测此选择.
- 如果没有线程符合条件,则信号将在进程级别保持"待定"状态,直到某个线程符合条件.
此外,Moshe Bar的"Linux信号处理模型"指出 "异步信号被传送到发现没有阻塞信号的第一个线程.",我解释为这意味着信号被传送到某个线程,其信号不包括信号.
哪一个是正确的?
关于第二个问题,堆栈会发生什么,并为所选线程注册内容?假设线程到运行信号处理程序T正在执行do_stuff()函数.线程T的堆栈是否直接用于执行信号处理程序(即信号trampoline的地址被压入T的堆栈并且控制流程转到信号处理程序)?或者,是否使用单独的堆栈?它是如何工作的?
在Linux/Unix上有信号.在CtrlC一个(SIGINT)是显而易见的我.现在,在其他一些应用程序中有信号通过CtrlX?!这甚至是信号还是产生逃逸序列?还有什么我可以用作类似CtrlC(CtrlV,CtrlX...)的东西吗?
如果有人有线索,我不熟悉C而不是bash,但是对这两种语言的答案表示赞赏!
我有一个应用程序,我用它来捕获任何分段错误或ctrl-c.使用下面的代码,我能够捕获分段错误,但是一次又一次地调用处理程序.我怎么能阻止他们.为了您的信息,我不想退出我的申请.我只需要注意释放所有损坏的缓冲区.
可能吗?
void SignalInit(void )
{
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = mysighandler;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
sigaction(SIGSEGV, &sigIntHandler, NULL);
}
Run Code Online (Sandbox Code Playgroud)
和处理程序是这样的.
void mysighandler()
{
MyfreeBuffers(); /*related to my applciation*/
}
Run Code Online (Sandbox Code Playgroud)
这里对于Segmentation故障信号,处理程序被多次调用,很明显,MyfreeBuffers()给了我释放已经释放的内存的错误.我只想释放一次,但仍然不想退出应用程序.
请帮忙.
我正在做这样的事情:
#include <signal.h>
class myClass {
public:
void myFunction ()
{
signal(SIGIO,myHandler);
}
void myHandler (int signum)
{
/**
* Handling code
*/
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用gcc在Ubuntu上工作.
但它不会编译.它抱怨:
错误:类型的参数
void (MyClass::)(int)不一致void (*) (int)
有线索吗?或者也许只是我不能在课程中使用信号?信号是否仅允许在C中?
错误消息是近似翻译,因为我的编译器不是英文.
在Linux下的python 2.6中,我可以使用以下内容来处理TERM信号:
import signal
def handleSigTERM():
shutdown()
signal.signal(signal.SIGTERM, handleSigTERM)
Run Code Online (Sandbox Code Playgroud)
有没有办法为进程收到的所有信号设置处理程序,而不是一次一个地设置它们?