C 计时器\创建返回EINVAL的函数

C 计时器\创建返回EINVAL的函数,c,linux,timer,linux-kernel,C,Linux,Timer,Linux Kernel,我正在编写一个示例程序,其中main()将创建一个线程,然后启动一个计时器。当计时器过期时,线程应该得到信号。这是在Ubuntu 18.04.4 LTS上 我的问题是计时器_create()失败,错误号设置为EINVAL。下面给出了我的timer_create()代码片段 /* Create the timer */ sevp.sigev_notify = SIGEV_THREAD_ID; sevp.sigev_signo = SIGALRM; sevp.sige

我正在编写一个示例程序,其中main()将创建一个线程,然后启动一个计时器。当计时器过期时,线程应该得到信号。这是在Ubuntu 18.04.4 LTS上

我的问题是计时器_create()失败,错误号设置为EINVAL。下面给出了我的timer_create()代码片段

    /* Create the timer */
    sevp.sigev_notify = SIGEV_THREAD_ID;
    sevp.sigev_signo = SIGALRM;
    sevp.sigev_value.sival_int = somevalue;
    sevp._sigev_un._tid = threadid;

    retval = timer_create(CLOCK_MONOTONIC,&sevp,&timerid);

    if ( 0 == retval )
    {
        printf("Success in creating timer [%p]",timerid);
    }
    else
    {
        printf("Error in creating timer [%s]\n",strerror(errno));
    }


我做错了什么?

根据带有
SIGEV\u线程ID的
timer\u create
的linux手册页条目:


至于SIGEV_信号,但该信号是针对线程的 其ID在sigev_notify_thread_ID中给出,该ID必须是 线程与调用方位于同一进程中。这个 sigev_notify_thread_id字段指定内核线程id, 即克隆(2)或getId(2)返回的值。这 该标志仅用于线程库


线程ID(问题代码中的
threadid
)需要是内核线程ID。可以使用
getID

什么是
threadid
?你确定这是一个有效的id吗?你用过pthreads id吗?@PiRocks是的,我用的是pthreads id。“至于SIGEV_信号,但该信号的目标是SIGEV_notify_thread_ID中给出ID的线程,该线程必须与调用方处于同一进程中。sigev_notify_thread_id字段指定一个内核线程id,即克隆(2)或gettid(2)返回的值。“重要的是,您应该使用内核tid而不是pthreads id。这解决了您的问题吗?@PiRocks..是的,我必须使用gettid()而不是pthread_self()。这些是不同的。在此之后,我的代码可以工作。非常感谢。请创建一个答案,以便我可以将其标记为正确。再次感谢。标准C库通常不提供
getId()
,但您可以
#包括
,并将其实现为
静态内联pid_t getId(void){返回syscall(SYS_getId)}
,适用于那些碰巧还不知道这一点的人。(不幸的是,我们没有可靠的方法来映射
pthread\u t
s和
tid
s。)