2015-10-19 27 views
3

我多线程化代码的工作,其中螺纹具有睡特定时间。我不想浪费CPU周期并想要/不得不使用定时器。这或多或少是我想要达到的。使用定时器和信号,而不是睡眠C/C++

我的单线程代码似乎是工作的罚款。

#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; 
} 

但是我的多线程卡在执行中。我的主线程停留在等待线程,线程1卡在设置计时器。任何想法为什么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,很类似,只是它采用相对时钟
  3. 使用timer_settime(脉冲),脉冲线程等待给定的时间了nanosleep终于同步输出
+3

了利用多线程程序的信号时要小心,将信号传递到*流程*,你不知道哪个线程实际上会抓住它。为了只接收特定线程中的信号,所有其他线程都应该阻止信号。请阅读[signal(7)'手册页](http://man7.org/linux/man-pages/man7/signal.7.html)。 –

+0

所以在这种情况下,只有线程2接收到的信号(因为它最后安装的处理器),以及另一个暂停永远反过来阻止你的主线程。 – rakeshdn

回答

0

我做了这样的

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); 
    } 
}