2012-04-23 58 views
5

我已經編寫了測試程序來測試出SCHED_FIFO。我知道SCHED_FIFO不能被SCHED_OTHER線程搶佔。但我無法解釋同一程序多次運行時獲得的結果。SCHED_FIFO線程被Linux中的SCHED_OTHER線程佔用

/* 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) */ 

我有在多個運行意外的結果,其中我看到SCHED_FIFOSCHED_OTHER線程搶佔,即作爲每個節目,線程2是在FIFO模式中,當線程1是SCHED_OTHER模式。我多次看到thread2被thread1搶佔的地方。

有人可以幫我找出問題嗎?

+0

'sysctl -a | grep _rt'? – ninjalj 2012-04-23 20:46:15

+0

@martinjames kernel.sched_rt_period_us = 1000000 kernel.sched_rt_runtime_us = 950000 – GoT 2012-04-24 02:57:13

+0

我使用Ubuntu 11.10使用g ++ 4.6.1 – GoT 2012-04-24 03:28:59

回答

6

你可能有效果sysctl的設置,這些設置都是默認值:

kernel.sched_rt_period_us = 1000000 
kernel.sched_rt_runtime_us = 950000 

這意味着,實時線程被允許生豬每1秒週期的只有95%。

另見:Can't provoke Priority Inversion in C++

+0

是的,這些都是我的默認values.But,我試圖把-1 kernel.sched_rt_runtime_us禁用實時。這也沒有解決 – GoT 2012-04-24 02:58:38

+4

你有多少核心?你如何確保線程不能簡單地在不同的內核上執行?另請注意,您必須設置優先級。 POSIX定義了一對函數'sched_get_priority_max'和'sched_get_priority_min',它們將策略作爲參數,併爲您提供該策略的有效優先級範圍。 – Kaz 2012-04-24 03:10:36

+1

我禁用了使用命令sudo sh -c「echo 0>/sys/devices/system/cpu/cpu3/online」的所有內核。事情很好.-) – GoT 2012-04-24 19:12:30

4

而且只要在你的IO線程塊,也許從printf報表,另一個線程可調度。