2012-04-23 20 views
5

vorgegangen. Ich habe Testprogramm geschrieben, um SCHED_FIFO zu testen. Ich habe gelernt, dass SCHED_FIFO nicht durch SCHED_OTHER Threads vorweggenommen werden kann. Aber ich konnte die Ergebnisse nicht erklären, die erhalten werden, wenn das gleiche Programm mehrmals ausgeführt wird.SCHED_FIFO Thread ist von SCHED_OTHER Thread in Linux

/* Includes */ 
#include <unistd.h>  /* Symbolic Constants */ 
#include <sys/types.h> /* Primitive System Data Types */ 
#include <errno.h>  /* Errors */ 
#include <stdio.h>  /* Input/Output */ 
#include <stdlib.h>  /* General Utilities */ 
#include <pthread.h> /* POSIX Threads */ 
#include <string.h>  /* String handling */ 
#include <sched.h> 
/* prototype for thread routine */ 
void print_message_function (void *ptr); 
void print_message_function1 (void *ptr); 

/* struct to hold data to be passed to a thread 
this shows how multiple data items can be passed to a thread */ 
typedef struct str_thdata 
{ 
int thread_no; 
int thread_value; 
char message[100]; 
    } thdata; 

int main() 
    { 
pthread_t thread1, thread2; /* thread variables */ 
thdata data1, data2;   /* structs to be passed to threads */ 

/* initialize data to pass to thread 1 */ 
data1.thread_no = 1; 
data1.thread_value = 0; 
strcpy(data1.message, "Hello!"); 

/* initialize data to pass to thread 2 */ 
data2.thread_no = 2; 
data2.thread_value = 10000; 
strcpy(data2.message, "Hi!"); 

/* create threads 1 and 2 */  
pthread_create (&thread1, NULL, (void *) &print_message_function, (void *) &data1); 
pthread_create (&thread2, NULL, (void *) &print_message_function1, (void *) &data2); 

/* Main block now waits for both threads to terminate, before it exits 
    If main block exits, both threads exit, even if the threads have not 
    finished their work */ 
pthread_join(thread1, NULL); 
pthread_join(thread2, NULL); 

/* exit */ 
exit(0); 
} /* main() */ 

/** 
* print_message_function is used as the start routine for the threads used 
* it accepts a void pointer 
**/ 
void print_message_function (void *ptr) 
{ 

thdata *data;    
data = (thdata *) ptr; /* type cast to a pointer to thdata */ 

struct sched_param param; 
//int priority=10; 
/* sched_priority will be the priority of the thread */ 
//param.sched_priority = priority; 
/* only supported policy, others will result in ENOTSUP */ 

int policy = SCHED_OTHER; 
/* scheduling parameters of target thread */ 
pthread_setschedparam(pthread_self(), policy, &param); 
printf("Thread %d says sched policy %d \n", data->thread_no, SCHED_OTHER); 
pthread_getschedparam(pthread_self(),&policy,&param); 

printf("Thread %d says %s %d \n", data->thread_no, data->message,policy); 

int i=0; 
/* do the work */ 
printf("Thread %d says %s %d \n", data->thread_no, data->message,(int)pthread_self()); 
for(i=0;i<100;i++) 

printf("Thread %d says %d \n", data->thread_no,data->thread_value++); 
pthread_exit(0); /* exit */ 
} /* print_message_function (void *ptr) */ 



void print_message_function1 (void *ptr) 
{ 

thdata *data;    
data = (thdata *) ptr; /* type cast to a pointer to thdata */ 

struct sched_param param; 
int priority=10; 
/* sched_priority will be the priority of the thread */ 
param.sched_priority = priority; 
/* only supported policy, others will result in ENOTSUP */

int policy = SCHED_FIFO; 
/* scheduling parameters of target thread */ 
pthread_setschedparam(pthread_self(), policy, &param); 
printf("Thread %d says sched policy %d \n", data->thread_no, SCHED_FIFO); 

pthread_getschedparam(pthread_self(),&policy,&param); 

printf("Thread %d says %s %d \n", data->thread_no, data->message,policy); 

int i=0; 
/* do the work */ 
printf("Thread %d says %s %d \n", data->thread_no, data->message,(int)pthread_self()); 
for(i=0;i<100;i++) 

printf("Thread %d says %d \n", data->thread_no,data->thread_value++); 
pthread_exit(0); /* exit */ 
} /* print_message_function (void *ptr) */ 

I unerwartete Ergebnisse in mehreren Läufen erhalten haben, wo ich SCHED_FIFO gesehen von SCHED_OTHER Gewinde preempted wird, das heißt wie im Programm, Faden 2 ist in FIFO Modus, während Thread 1 SCHED_OTHER-Modus ist. Ich habe mehrere Male gesehen, wo thread2 von thread1 verdrängt wird.

Kann mir jemand helfen, das Problem zu finden?

+0

Ausgabe von 'sysctl -a | grep _rt'? – ninjalj

+0

@martinjames kernel.sched_rt_period_us = 1000000 kernel.sched_rt_runtime_us = 950000 – GoT

+0

Ich benutze ubuntu 11.10 mit g ++ 4.6.1 – GoT

Antwort

6

Sie haben wahrscheinlich diese sysctl-Einstellungen in der Tat, die Standardwerte sind:

kernel.sched_rt_period_us = 1000000 
kernel.sched_rt_runtime_us = 950000 

Das bedeutet, dass Echtzeit-Threads nur 95% jeder Periode von 1 Sekunde in Beschlag zu nehmen sind erlaubt.

Siehe auch: Can't provoke Priority Inversion in C++

+0

ja, das sind meine Standardwerte. Aber ich habe versucht, -1 zu kernel.sched_rt_runtime_us zu setzen, um Realtime zu deaktivieren. Dies hat auch nicht funktioniert – GoT

+4

Wie viele Kerne haben Sie? Wie stellen Sie sicher, dass die Threads nicht einfach auf verschiedenen Kernen ausgeführt werden können? Beachten Sie auch, dass Sie die Priorität festlegen müssen. POSIX definiert ein Paar von Funktionen 'sched_get_priority_max' und' sched_get_priority_min', die eine Richtlinie als Argument annehmen und Ihnen den Bereich gültiger Prioritäten für diese Richtlinie angeben. – Kaz

+1

Ich deaktivierte die Verwendung aller Kerne außer einem Befehl sudo sh -c "echo 0>/sys/devices/system/cpu/cpu3/online" .. Dinge sind in Ordnung.THANKS :-) – GoT

4

Auch, wenn die Thread-Blöcke auf IO, vielleicht aus den printf Aussagen, kann ein anderer Thread geplant werden.