#include #include #include #include #include #include #include #include #include //ID pulsow #define PULSE_ID2 10 #define PULSE_ID3 11 //czas startu programu struct timeval start; //struktura wiadomosci typedef struct{ struct _pulse pulse; } msg; //do zapewnienia sekcji krytycznej pthread_mutex_t mut; //identyfikatory timerow timer_t timer1, timer2, timer3, timer4; //identyfikator kanalu int chid; //identyfikatory polaczen dla T2 i T3 int coid2, coid3; //funkcja wypisujaca komunikat oznaczony timestampem void timestamp(char* msg) { pthread_mutex_lock(&mut); //terminal jest chroniony mutexem struct timeval time; //pobranie aktualnego czasu gettimeofday(&time, NULL); int miliseconds = ((time.tv_sec-start.tv_sec)*1000000 + time.tv_usec-start.tv_usec)/1000; //czas od startu int seconds = miliseconds/1000; //sekundy miliseconds = miliseconds%1000; //milisekundy printf("%d:%03ld\t - %s\n", seconds, miliseconds , msg); pthread_mutex_unlock(&mut); } //watek T1 void thread1(void* args) { timestamp("Timer T1."); } //handler sygnalu SIGINT - zamyka program void signalHandler(int sigid) { //usuwanie timerow timer_delete(timer1); timer_delete(timer2); timer_delete(timer3); timer_delete(timer4); //zamykanie polaczen i kanalu ConnectDetach(coid2); ConnectDetach(coid3); ChannelDestroy(chid); timestamp("Timer T4. Koniec programu."); exit(EXIT_SUCCESS); } int main() { //eventy dla timerow struct sigevent event1, event2, event3, event4; //parametry timerow struct itimerspec itimerspec1, itimerspec2, itimerspec3, itimerspec4; int rcvid; msg message; //ustawienie handlera sygnalu signal(SIGINT, signalHandler); chid = ChannelCreate(0); //stworzenie eventu tworzacego watek SIGEV_THREAD_INIT (&event1, (void*)thread1, NULL, NULL); //czas pierwszego uruchomienia i powtarzania 0.5s itimerspec1.it_value.tv_sec = 0; itimerspec1.it_value.tv_nsec = 500000000; itimerspec1.it_interval.tv_sec = 0; itimerspec1.it_interval.tv_nsec = 500000000; //stworzenie eventu wywolujacego puls 2 coid2 = ConnectAttach(ND_LOCAL_NODE, 0, chid, _NTO_SIDE_CHANNEL, 0); SIGEV_PULSE_INIT (&event2, coid2, SIGEV_PULSE_PRIO_INHERIT, PULSE_ID2, NULL); //czas pierwszego uruchomienia i powtarzania 2s itimerspec2.it_value.tv_sec = 2; itimerspec2.it_value.tv_nsec = 0; itimerspec2.it_interval.tv_sec = 2; itimerspec2.it_interval.tv_nsec = 0; //stworzenie eventu wywolujacego puls 3 coid3 = ConnectAttach(ND_LOCAL_NODE, 0, chid, _NTO_SIDE_CHANNEL, 0); SIGEV_PULSE_INIT (&event3, coid3, SIGEV_PULSE_PRIO_INHERIT, PULSE_ID3, NULL); //czas pierwszego uruchomienia 5s, powtarzania 1s itimerspec3.it_value.tv_sec = 5; itimerspec3.it_value.tv_nsec = 0; itimerspec3.it_interval.tv_sec = 1; itimerspec3.it_interval.tv_nsec = 0; //stworzenie eventu wywolujacego SIGINT SIGEV_SIGNAL_INIT (&event4, SIGINT); //czas pierwszego i jedynego uruchomienia - 10s itimerspec4.it_value.tv_sec = 10; itimerspec4.it_value.tv_nsec = 0; itimerspec4.it_interval.tv_sec = 0; itimerspec4.it_interval.tv_nsec = 0; //stworzenie timerow dla eventow i zapamietanie ich id timer_create(CLOCK_REALTIME, &event1, &timer1); timer_create(CLOCK_REALTIME, &event2, &timer2); timer_create(CLOCK_REALTIME, &event3, &timer3); timer_create(CLOCK_REALTIME, &event4, &timer4); //ustawienie czasow timerow timer_settime(timer1, 0, &itimerspec1, NULL); timer_settime(timer2, 0, &itimerspec2, NULL); timer_settime(timer3, 0, &itimerspec3, NULL); timer_settime(timer4, 0, &itimerspec4, NULL); //zapisanie poczatkowego czasu programu gettimeofday(&start, NULL); timestamp("Start"); //odbieranie wiadomosci while(1) { rcvid = MsgReceive(chid, &message, sizeof(message), NULL); if(rcvid == 0) { if(message.pulse.code == PULSE_ID2) { timestamp("Timer T2."); } else if(message.pulse.code == PULSE_ID3) { timestamp("Timer T3."); } } } return 0; }