Wiederholung eines Threads konstant alle 10 Millisekunden



  • Hallo Forum,

    ich experiemtiere gerade mit Timern und Pthread mit C. Siehe Beispielprogramm.

    Meine Frage: Je nachdem, wieviel Code in den diversen Threads oder Timern ausgeführt wird dauert der Durchlauf des Threads mal länger oder mal kürzer. Ist es möglich, dass man den Thread konstant alle 10 Millisekunden wiederholen kann? Auch wenn der Thread noch nicht abgearbeitet wurde?

    Zusatz: Wird durch die Funktion timer_create() intern auch ein Thread gestartet?

    Vielen Dank

    Viel Grüße,
    eddi

    #include <stdio.h>
    
    #include <pthread.h>
    #include <signal.h>
    #include <time.h>
    #include <unistd.h>
    
    timer_t TIMER_task_100msID;
    timer_t TIMER_task_10msID;
    timer_t TIMER_task_1msID;
    
    pthread_t thread;
    
    static void MAIN_Task_100ms()
    {
    	printf("100ms\n");
    }
    
    static void MAIN_Task_10ms()
    {
    	printf("10ms\n");
    }
    
    static void MAIN_Task_1ms()
    {
    	printf("1ms\n");
    }
    
    static void timerHandler(int signal, siginfo_t *siginfo, void *callback)
    {	
    	timer_t *timerID;
    	timerID = siginfo->si_value.sival_ptr;
    
    	(void)callback;
    	(void)signal;
    
    	if (*timerID == TIMER_task_100msID)
    	{
    		MAIN_Task_100ms();
    	}
    	else if (*timerID == TIMER_task_10msID)
    	{
    		MAIN_Task_10ms();
    	}
    	else if (*timerID == TIMER_task_1msID)
    	{
    		MAIN_Task_1ms();
    	}
    }
    
    static void TIMER_Init(timer_t *timerID, int interval, int expire)
    {
    	int ret;
    	struct sigevent sigEvent;
    	struct itimerspec timerSpec;
    	struct sigaction sigAction;
    	int sigNo = SIGRTMIN;
    
    	sigAction.sa_flags = SA_SIGINFO;
    	sigAction.sa_sigaction = timerHandler;
    	sigemptyset(&sigAction.sa_mask);
    	sigaction(sigNo, &sigAction, NULL);
    
    	sigEvent.sigev_notify = SIGEV_SIGNAL;
    	sigEvent.sigev_signo = sigNo;
    	sigEvent.sigev_value.sival_ptr = timerID;
    	timer_create(CLOCK_REALTIME, &sigEvent, timerID);
    
    	timerSpec.it_interval.tv_sec = 0;
    	timerSpec.it_interval.tv_nsec = interval * 1000;
    	timerSpec.it_value.tv_sec = 0;
    	timerSpec.it_value.tv_nsec = expire * 1000;
    	timer_settime(*timerID, 0, &timerSpec, NULL);
    }
    
    static void timespec_add_us(struct timespec *t, long us)
    {
    	t->tv_nsec += us * 1000;
    	if (t->tv_nsec > 1000000000) {
    		t->tv_nsec = t->tv_nsec - 1000000000;
    		t->tv_sec += 1;
    	}
    }
    
    static void *thread_run(void *arg)
    {
    	struct timespec next;
    
    	clock_gettime(CLOCK_REALTIME, &next);
    
    	while (1)
    	{		
    		timespec_add_us(&next, 1000000);
    		clock_nanosleep(CLOCK_REALTIME, 0, &next, NULL);
    		printf("Thread start\n");
    	}
    	printf("Thread ende\n");
    
    	return NULL;
    }
    
    int main()
    {
    	TIMER_Init(&TIMER_task_100msID, 100000,  100000);
    	TIMER_Init(&TIMER_task_10msID,   10000,   10000);
    	TIMER_Init(&TIMER_task_1msID,     1000,    1000);
    
    	pthread_create(&thread, NULL, thread_run, NULL);
    
    	while (1);
    
    	return 0;
    }
    


  • Ist es möglich, dass man den Thread konstant alle 10 Millisekunden wiederholen kann? Auch wenn der Thread noch nicht abgearbeitet wurde?

    wie kann es konstant 10ms sein wenn der Thread länger braucht? oder was meinst du



  • Ich möchte, dass der Thread wieder gestartet wird, auch wenn er noch nicht abgearbeitet wurde. Wenn ich es mir recht überlege, wäre dass ja dann ein neuer Thread. Es so etwas überhaupt möglich?

    Mein Ziel ist in diesem Thread ein Zähler mitlaufen zu lassen, so dass ich die Zeit messen kann. z.B. 10 Takte a 10ms wären dann 100ms. Und diese 100ms sollten auch in der Realität 100ms entsprechen.



  • Was immer Du auch machen möchtest - DEN THREAD kannst Du natürlich nicht zweimal starten.
    Aber:
    Der Thread führt ja eine Funktion aus. Und Du kannst selbstverständlich dieselbe Funktion alle 10 ms von einem neuen Thread ausführen lassen, unabhängig davon, ob der/die vorher gestarteten Threads fertig sind oder nicht.



  • Hallo.
    Mein Problem lag gar nicht an den aufrufen der Threads sondern an der Konfiguration der Timer. Durch die Fehlkonfiguration haben sich die Threads und die Timer gegenseitig gestört. Durch irgendwelche Signale. Da bin ich aber auch überfragt, was da genau intern passiert. Nun funktioniert es jedenfalls wie es soll.

    Die Änderungen:

    #include <sys/syscall.h>
    
    static void TIMER_Init(timer_t *timerID, int interval, int expire)
    {
        int ret;
        struct sigevent sigEvent;
        struct itimerspec timerSpec;
        struct sigaction sigAction;
        /*int sigNo = SIGRTMIN;*/
        int sigNo = SIGRTMAX;
    
        sigAction.sa_flags = SA_SIGINFO;
        sigAction.sa_sigaction = timerHandler;
        sigemptyset(&sigAction.sa_mask);
        sigaction(sigNo, &sigAction, NULL);
    
        /*sigEvent.sigev_notify = SIGEV_SIGNAL;*/
        sigEvent.sigev_notify = SIGEV_THREAD_ID;
        sigEvent._sigev_un._tid = syscall(__NR_gettid);
        sigEvent.sigev_signo = sigNo;
        sigEvent.sigev_value.sival_ptr = timerID;
        timer_create(CLOCK_REALTIME, &sigEvent, timerID);
    
        timerSpec.it_interval.tv_sec = 0;
        timerSpec.it_interval.tv_nsec = interval * 1000;
        timerSpec.it_value.tv_sec = 0;
        timerSpec.it_value.tv_nsec = expire * 1000;
        timer_settime(*timerID, 0, &timerSpec, NULL);
    }
    

Anmelden zum Antworten