【发布时间】:2014-11-11 10:55:04
【问题描述】:
在一次性计时器的情况下,我可以使用信号量来等待计时器回调完成。 但是,如果计时器被多次触发,它就没有帮助。考虑以下代码:
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#define N 10
void timer_threaded_function(sigval_t si)
{
uint8_t *shared_resource = si.sival_ptr;
sleep(rand() % 7);
/* ... manipulate with shared_resource */
return;
}
int main()
{
struct sigevent sig_ev = {0};
uint8_t *shared_resource = malloc(123);
timer_t timer_id;
int i;
sig_ev.sigev_notify = SIGEV_THREAD;
sig_ev.sigev_value.sival_ptr = shared_resource;
sig_ev.sigev_notify_function = timer_threaded_function;
sig_ev.sigev_notify_attributes = NULL;
timer_create(CLOCK_REALTIME, &sig_ev, &timer_id);
for (i = 0; i < N; i++) {
/* arm timer for 1 nanosecond */
timer_settime(timer_id, 0,
&(struct itimerspec){{0,0},{0,1}}, NULL);
/* sleep a little bit, so timer will be fired */
usleep(1);
}
/* only disarms timer, but timer callbacks still can be running */
timer_delete(timer_id);
/*
* TODO: safe wait for all callbacks to end, so shared resource
* can be freed without races.
*/
...
free(shared_resource);
return 0;
}
timer_delete() 只解除计时器(如果它被武装)并释放与计时器相关的资源。但是计时器回调仍然可以运行。所以我们不能释放shared_resource,否则可能会出现竞争情况。有什么办法可以应对这种情况吗?
我想到了引用计数,但它没有帮助,因为我们不知道实际上有多少线程会尝试访问共享资源(导致计时器溢出)。
【问题讨论】:
-
您如何确定一定数量的分离线程完成了对共享资源的操作?解决这个问题,你就解决了这个问题。
timer_API 有点像红鲱鱼 - 分离的线程是由计时器、信号、调用pthread_create()的循环创建的,不管怎样。
标签: c linux multithreading timer pthreads