多线程环境下的信号处理
2010-06-24 23:23
274 查看
函数有线程安全和异步信号安全的分别,线程安全指的是在多线程环境下(函数可能同时有几个线程正在调用)是安全的;异步信号安全指的是即使被信号处理函数打断执行,在处理函数里面再次调用此函数依然没有问题,不会产生不良影响。比如mutex是线程安全的,但不是异步信号安全的。malloc也不是异步信号安全的。
实现里面的station类有若干个实例,每一个实例都存在于一个单独的派生线程中,每一个进程都需要一个定时器,时长不一样。定时器处理函数里面都需要处理各自实例的数据。这里就碰到了几个问题:如何防止在定时器处理函数里面和类的主流程数据访问冲突;如何在处理函数里面得到实例的指针。
因为对多线程环境的信号处理不熟悉,所以编了一个测试的小程序。主线程设置SIGALRM的处理函数T,在T里面再次调用alarm(5);工作线程P有3个,都设置其超时处理函数为T。P里面是一个死循环,每次sleep(6)。然后打印出sleep前后的时间差。根据输出到文件的信息,可以知道其实把线程理解成为一个进程就OK了,只是
主线程的信号量设置(block等)可以被派生的线程继承,但是各自的信号处理和设置都可以是单独的。利用pthread_kill可以想指定的线程发送信号,与sigwait则可以实现信号的同步处理。注意的是在派生线程里面,printf的输出并不显示到STDOUT,可能是被重定向了,还不清楚。
一个方法是可以在各个派生线程里面自己处理SIGALRM信号,但是如何获取本线程的STATION实例呢?信号处理函数不能传入,只能依靠全局变量,但是当时却没有想到简单的方法区分出各自线程独有的数据,晚上却突然想到了类似与getpid,pthread肯定也提供API得到本线程的id,一查果然是有pthread_self。这种方法下处理数据访问冲突比较简单,主流程里面在访问数据前设置一个标记即可,类似于mutex,此时不能用pthread_mutex_t,因为他不是异步线程安全的。
另外一个方法是采用sigwait的同步处理方法,创建一个线程专用于处理信号量,各个线程向他注册信号处理的回调函数,由他负责在合适的时候调用。这时候,由于STATION线程的回调函数不是在信号中断上下文中执行,所以可以采用pthread_mutex_t。
当时遇到的一个问题是开始只是在信号处理线程中block了SIGALRM信号,主线程没有设置掩码,导致主线程过了几秒钟就会退出。一开始很是纳闷,后来用gdb调试才看到是因为有SIGALRM,才知道是怎么回事。不过为什么一定要在主线程中block呢?我的alarm也是在信号处理线程里面的啊?难道在派生线程中产生的信号,也会被递到主线程中?明天有时间还得仔细测试下。
前一种方法相对简单(可行的话),逻辑也比较清楚,但是会打断主流程;后一种方法看起来很美,并且在不同的线程执行,对主任务影响不大,缺点是如果管理的定时任务多的话,后续的定时会有明显的延迟,并且使用mutex(try lock)。打算先用着第二种方法,将来有必要再来改进。
gdb的几个thread调试命令:infor thread, thread [id], 还有一个设置是否所有线程同时挂起的命令给忘了。
还有很多任务要做:多实例化,改进目前的IO模型,有无必要使用splitter模式等等。
实现里面的station类有若干个实例,每一个实例都存在于一个单独的派生线程中,每一个进程都需要一个定时器,时长不一样。定时器处理函数里面都需要处理各自实例的数据。这里就碰到了几个问题:如何防止在定时器处理函数里面和类的主流程数据访问冲突;如何在处理函数里面得到实例的指针。
因为对多线程环境的信号处理不熟悉,所以编了一个测试的小程序。主线程设置SIGALRM的处理函数T,在T里面再次调用alarm(5);工作线程P有3个,都设置其超时处理函数为T。P里面是一个死循环,每次sleep(6)。然后打印出sleep前后的时间差。根据输出到文件的信息,可以知道其实把线程理解成为一个进程就OK了,只是
主线程的信号量设置(block等)可以被派生的线程继承,但是各自的信号处理和设置都可以是单独的。利用pthread_kill可以想指定的线程发送信号,与sigwait则可以实现信号的同步处理。注意的是在派生线程里面,printf的输出并不显示到STDOUT,可能是被重定向了,还不清楚。
一个方法是可以在各个派生线程里面自己处理SIGALRM信号,但是如何获取本线程的STATION实例呢?信号处理函数不能传入,只能依靠全局变量,但是当时却没有想到简单的方法区分出各自线程独有的数据,晚上却突然想到了类似与getpid,pthread肯定也提供API得到本线程的id,一查果然是有pthread_self。这种方法下处理数据访问冲突比较简单,主流程里面在访问数据前设置一个标记即可,类似于mutex,此时不能用pthread_mutex_t,因为他不是异步线程安全的。
另外一个方法是采用sigwait的同步处理方法,创建一个线程专用于处理信号量,各个线程向他注册信号处理的回调函数,由他负责在合适的时候调用。这时候,由于STATION线程的回调函数不是在信号中断上下文中执行,所以可以采用pthread_mutex_t。
当时遇到的一个问题是开始只是在信号处理线程中block了SIGALRM信号,主线程没有设置掩码,导致主线程过了几秒钟就会退出。一开始很是纳闷,后来用gdb调试才看到是因为有SIGALRM,才知道是怎么回事。不过为什么一定要在主线程中block呢?我的alarm也是在信号处理线程里面的啊?难道在派生线程中产生的信号,也会被递到主线程中?明天有时间还得仔细测试下。
前一种方法相对简单(可行的话),逻辑也比较清楚,但是会打断主流程;后一种方法看起来很美,并且在不同的线程执行,对主任务影响不大,缺点是如果管理的定时任务多的话,后续的定时会有明显的延迟,并且使用mutex(try lock)。打算先用着第二种方法,将来有必要再来改进。
gdb的几个thread调试命令:infor thread, thread [id], 还有一个设置是否所有线程同时挂起的命令给忘了。
还有很多任务要做:多实例化,改进目前的IO模型,有无必要使用splitter模式等等。
相关文章推荐
- 在多线程程序中指定线程来处理信号
- 多线程----信号处理
- Linux 多线程应用中编写安全的信号处理函数
- matlab环境下连续信号采样处理的仿真分析设计
- UNIX环境编程学习笔记(24)——信号处理进阶学习之信号集和进程信号屏蔽字
- C# 多线程并发处理数据库数据,发送信号等待处理完统一插入.
- 多线程环境下处理未捕获的异常
- Linux 多线程应用中如何编写安全的信号处理函数
- Linux下信号处理与多线程程序
- C# 多线程并发处理数据库数据,发送信号等待处理完统一插入.(转)
- GraphicsMagick在多线程环境工作时其自身多线程处理会变成单线程
- Linux 多线程应用中如何编写安全的信号处理函数
- Linux 多线程应用中如何编写安全的信号处理函数
- Linux 多线程应用中如何编写安全的信号处理函数
- Linux 多线程应用中编写安全的信号处理函数
- PDA环境下GPS信号的接收和处理方法
- 信号屏蔽字在多线程环境下的应用
- iOS多张图片上传多线程处理方法(可获取最后一张上传状态后的信号)
- Linux 多线程应用中编写安全的信号处理函数
- Linux 多线程应用中的信号处理