【发布时间】:2017-03-14 04:52:13
【问题描述】:
timer_settime() 每秒构建计时器。信号处理程序是traffic_measurement_handler。 traffic_measurement_handler 是否在新线程中运行?处理程序运行时如何让callback停止?
#define CLOCKID CLOCK_REALTIME
#define SIG SIGUSR1
timer_t timerid;
int main(void)
{
..
build_timer();
pcap_loop(pcap_handle, -1, callback, NULL);
}
void callback() // callback of Libpcap API: pcap_loop()
{
detect_network_traffic(); // stop when timer expires, and then continue
// to run when traffic_measurement_handler has finished.
}
// timer handler runs every second to update database
void traffic_measurement_handler()
{
.. // This block will fetch global variables, so I want to
// let callback stop when this handler is running.
// rebuild the timer
build_timer();
}
// set timer
void build_timer()
{
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = traffic_measurement_handler;
sigemptyset(&sa.sa_mask);
sigaction(SIG, &sa, NULL);
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIG;
sev.sigev_value.sival_ptr = &timerid;
timer_create(CLOCKID, &sev, &timerid);
its.it_value.tv_sec = 1;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = its.it_value.tv_sec;
its.it_interval.tv_nsec = its.it_value.tv_nsec;
timer_settime(timerid, 0, &its, NULL);
}
信号处理程序在只存在一个线程的进程中是否安全?
添加:第二版
是这样吗?
pthread_t thread_global;
int main(void)
{
// register SIGUSR1 handler
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = traffic_measurement_handler;
sigemptyset(&sa.sa_mask);
sigaction(SIG, &sa, NULL);
pthread_create(&thread1, NULL, processing_thread, (void *) thread_id1);
pthread_create(&thread2, NULL, timer_thread, (void *) thread_id2);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
}
void *processing_thread(void *thread_id)
{
pcap_loop(pcap_handle, -1, callback, NULL);
}
void callback() // callback of Libpcap API: pcap_loop()
{
thread_global = pthread_self();
detect_network_traffic(); // stop when SIGUSR1 is caught, and then continue
// to run when traffic_measurement_handler has finished.
}
//update database every second when SIGUSR1 is caught
void traffic_measurement_handler()
{
..
}
//This thread is used to notify updating database every second.
void *timer_thread(void *thread_id)
{
for (; ;) {
sleep(1);
pthread_kill(thread_global, SIGUSR1);
}
}
【问题讨论】:
-
这取决于您传递给
timer_create的参数值。阅读timer_create man page。它告诉您如何根据参数调用函数。如果您需要进一步的帮助,请显示minimal reproducible example。 -
@kaylum 我已经添加了示例代码。
-
如果将 sigev_notify 设置为 SIGEV_THREAD 而不是 SIGEV_SIGNAL,则回调将作为新线程运行。现在它作为信号处理程序运行。
-
@Ali Volkan ATLI,谢谢。那么
callback和traffic_measurement_handler在同一个线程中吗? -
@hel,还是不行,2.6 posix线程,信号被发送到进程,由根线程接收和处理。 pcap_loop 创建另一个线程,所以它会在不同的线程上