2015-10-19 29 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); 
    } 
}