【问题标题】:using timer and signal instead of sleep c/c++使用定时器和信号代替睡眠 C/C++
【发布时间】:2015-10-19 07:36:32
【问题描述】:

我正在处理多线程代码,其中线程必须休眠特定时间。我不想浪费 CPU 周期并且想要/必须使用计时器。这或多或少是我想要实现的。

我的单线程代码似乎运行良好。

#include <cstdlib>
#include <iostream>
#include <time.h>
#include <sys/siginfo.h>
#include <signal.h>
#include <unistd.h>

volatile sig_atomic_t print_flag = false;

void handle_alarm(int sig)
{
    print_flag = true;
}

int main(int argc, char *argv[])
{
    //struct sigevent event;


    signal( SIGALRM, handle_alarm ); // Install handler first,

    timer_t timerid;
    struct itimerspec timer;

    timer_create(CLOCK_REALTIME,NULL,&timerid);

    timer.it_value.tv_sec = 1;
    timer.it_value.tv_nsec = 0;
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_sec = 0;

    std::cout << "Setting timer" << std::endl;

    timer_settime(timerid,0,&timer,NULL);

    pause();

    std::cout << "Hello\n" << std::endl;

    return EXIT_SUCCESS;
}

但我的多线程卡在执行中。我的主线程卡在等待线程,而 thread1 卡在设置计时器上。知道为什么 thread1 没有完成执行吗?

#include <cstdlib>
#include <iostream>
#include <time.h>
#include <sys/siginfo.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>


volatile sig_atomic_t print_flag = false;

void handle_alarm(int sig)
{
    print_flag = true;
}
void *mythread(void* time)
{
    signal( SIGALRM, handle_alarm ); // Install handler first,

    timer_t timerid;
    struct itimerspec timer;

    timer_create(CLOCK_REALTIME,NULL,&timerid);

    timer.it_value.tv_sec = *(int*)time;
    timer.it_value.tv_nsec = 0;
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_sec = 0;

    std::cout << "Setting timer" << std::endl;

    timer_settime(timerid,0,&timer,NULL);

    pause();

    std::cout << "Hello" << *(int*)time << std::endl;

}

int main(int argc, char *argv[])
{

    pthread_t thread1, thread2;

    std::cout << "Started threads\n" << std::endl;

    int temp1 = 10,temp2 = 5;

    pthread_create(&thread1, NULL, &mythread,(void*) &temp1);
    pthread_create(&thread2, NULL, &mythread,(void*) &temp2);

    std::cout << "Waiting for threads\n" << std::endl;

    pthread_join(thread1,NULL);
    pthread_join(thread2,NULL);

    std::cout << "Done\n" << std::endl;

    return EXIT_SUCCESS;
}

编辑:

我通过几种方法做到了,

  1. 通过使用 nanosleep,它只解决了一个问题,忙等待。
  2. 使用clock_nanosleep,它类似于nanosleep,只是它使用相对时钟
  3. 使用 timer_settime (pulse),线程等待给定时间的脉冲,最后打卡

【问题讨论】:

  • 在多线程程序中使用信号时要小心,信号被传递到进程,而你不知道哪个线程会实际捕获它。要仅在特定线程中接收信号,所有其他线程都应阻塞该信号。阅读更多关于它的信息in the signal(7) manual page
  • 所以在这种情况下,只有线程 2 收到了信号(因为它最后安装了处理程序),而另一个则永远暂停,依次阻塞你的主线程。

标签: c++ multithreading timer


【解决方案1】:

我是这样做的

struct sigevent         event;
struct itimerspec       itime;
timer_t                 timer_id;
int                     chid, rcvid;
my_message_t            msg;

chid = ChannelCreate(0);

// following code is used to get kick every pulse period time
// which is 20ms
event.sigev_notify = SIGEV_PULSE;
event.sigev_coid = ConnectAttach(ND_LOCAL_NODE, 0,
        chid,
        _NTO_SIDE_CHANNEL, 0);
event.sigev_priority = getprio(0);
event.sigev_code = _PULSE_CODE_MINAVAIL;
timer_create(CLOCK_REALTIME, &event, &timer_id);

// 20 ms to nano seconds
itime.it_value.tv_sec = 0;
itime.it_value.tv_nsec = 20000000;
itime.it_interval.tv_sec = 0;
itime.it_interval.tv_nsec = 20000000;
timer_settime(timer_id, 0, &itime, NULL);

SERVO1DELAY1.tv_sec = 0;
SERVO1DELAY1.tv_nsec = 100000;

while(1)
{
    rcvid = MsgReceive(chid, &msg, sizeof(msg), NULL);
    if (rcvid == 0)
    {
        // make pulse high for appropriate time
        out8( data_handle_A, HIGH );
        InterruptDisable();
        nanospin(&SERVO1DELAY1);
        InterruptEnable();
        out8( data_handle_A, LOW );
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多