【发布时间】:2015-07-02 05:16:59
【问题描述】:
我正在编写一个简单的测试来分析多线程应用程序在使用 POSIX 计时器时的行为。
我正在创建 3 个线程、3 个计时器、3 个事件和 3 个 timerspecs。
我要做的是让每个线程设置一个计时器,等待计时器到期(这会释放不安全的锁)并完成线程。
但是,当我运行以下程序时,只有第一个计时器到期,这让我相信每个进程可能不可能有多个计时器。有什么问题吗?
handle(union sigval params)是每个定时器到期时的回调。threadTask(void *params)是每个线程执行的回调。
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <pthread.h>
typedef struct TH_PARAMS
{
uint threadNum;
pthread_t tid;
timer_t *timer;
struct sigevent *event;
} ThreadParams_t;
static timer_t timers[3];
static struct itimerspec timeToWait[3];
static struct sigevent events[3];
static ThreadParams_t thParams[3];
static char wait[3];
static void handle(union sigval params)
{
ThreadParams_t *threadParams = (ThreadParams_t *) params.sival_ptr;
printf("Timer %d expired. Thread num which sent %d. Thread %ld. Pthread %ld.\n",
*((int*) *(threadParams->timer)), threadParams->threadNum,
syscall(SYS_gettid), pthread_self());
wait[threadParams->threadNum] = 0;
}
static void *threadTask(void *params)
{
ThreadParams_t *threadParams = (ThreadParams_t *) params;
printf("Thread num %d. Thread %ld. Pthread %ld.\n",
threadParams->threadNum, syscall(SYS_gettid),
pthread_self());
if (0 != timer_settime(threadParams->timer, 0, &timeToWait[threadParams->threadNum], NULL))
{
printf("Failed to set timers. Error %d.\n", errno);
pthread_exit(NULL);
}
while(wait) sleep(1);
pthread_exit(NULL);
}
int main()
{
int i;
printf("Main thread started. Thread: %ld. Pthread: %ld\n", syscall(SYS_gettid), pthread_self());
for (i = 0; i < 3; ++i)
{
timeToWait[i].it_value.tv_sec = 2;
timeToWait[i].it_value.tv_nsec = 0;
timeToWait[i].it_interval.tv_sec = 0;
timeToWait[i].it_interval.tv_nsec = 0;
events[i].sigev_notify = SIGEV_THREAD;
events[i].sigev_notify_function = handle;
events[i].sigev_value.sival_ptr = &thParams[i];
if (0 != timer_create(CLOCK_MONOTONIC, &events[i], &timers[i]))
{
printf("Failed to create timers. Error %d.\n", errno);
return 1;
}
wait[i] = 1;
thParams[i].threadNum = i;
thParams[i].event = &events[i];
thParams[i].timer = &timers[i];
if (0 != pthread_create(&thParams[i].tid, NULL, threadTask, (void *) &thParams[i]))
{
printf("Failed to create thread. Error %d.\n", errno);
for (i = 0; i < 3; ++i)
{
if (timers[i])
{
timer_delete(timers[i]);
}
}
return 1;
}
}
for (i = 0; i < 3; ++i)
{
pthread_join(thParams[i].tid, NULL);
}
for (i = 0; i < 3; ++i)
{
if (timers[i])
{
timer_delete(timers[i]);
}
}
printf("Main thread finished. Thread: %ld.\n", syscall(SYS_gettid));
return 0;
}
【问题讨论】:
-
man timer_create: [...]The kernel preallocates a "queued real-time signal" for each timer created using timer_create(). Consequently, the number of timers is limited by the RLIMIT_SIGPENDING resource limit (see setrlimit(2)).[...]