简体   繁体   中英

timer_create for multiple threads in C++

Multiple threads call a method and setup a timer with timer_create and timer_settime. I am trying to pass the thread id in

sev.sigev_value.sival_ptr = &info;

however when the handler is called it comes with a different thread id (probably the main function's id) and my cancel method is not called.

        timer_t timerid;
        struct sigevent sev;
        struct itimerspec its;
        long long freq_nanosecs;
        sigset_t mask;
        struct sigaction sa; 

        sa.sa_flags = SA_SIGINFO;
        sa.sa_sigaction = &handler;
        sigemptyset(&sa.sa_mask);
        sigaction(SIGUSR1, &sa, NULL);

        sev.sigev_notify = SIGEV_SIGNAL;
        sev.sigev_signo = SIGUSR1;
        sev.sigev_value.sival_ptr = &info;
        timer_create(CLOCK_REALTIME, &sev, &timerid);
        /* Start the timer */

        its.it_value.tv_sec = 3;
        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);

Now the handler is

        Info *inc;
        inc = (Info *)si->si_value.sival_ptr;

        std::thread::id thread_id = std::this_thread::get_id();

        if(inc->thread_id != thread_id){
                LOG << "This thread is not blocking";
        } else {
                printf("Caught signal %d from timer\n", sig);

                cancel(...);
        }

My problem is that I cannot correctly identify a proper way to identify to call the cancel method based on a unique value that comes from the calling thread.

Any suggestion

A blocking connect or read / recv / recvmsg / recvfrom return EINTR when interrupted by a signal and no SA_RESTART is used for that signal. This was the main intention behind alarm syscall, however, it was invented before multi-threading, so it sends the signal to the process rather than a specific thread.

To break from a blocking socket connect call set a timer that sends a signal to the particular thread using SIGEV_THREAD_ID . Send the signal handler to SIG_IGN and make sure SA_RESTART is not used for that signal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM