[완료]pthread scheduling 관련 질문입니다.
일단 제가 원하는 것은 우선 순위가 50, 55인 쓰레드 두개를 라운드 로빈 스케줄링 정착하에 실행 시킵니다.
스레드가 하는 일은 그냥 간단하게 10000을 카운터하면 화면에 출력합니다.
제가 예상하기로는 두 쓰레드게 병렬적으로 수행하고 55의 우선 순위를 가지는 쓰레드가 50 보다 먼저 종료 되어야합니다. 그런데 이상하게 우선 순위가 50인 쓰레드 종료후 55인 쓰레드가 실행을 시작합니다. 즉 선점도 병렬수행도 안되는듯한데요...
(참고로 우순 순위가 50 인 것을 먼저 생성 하고 55을 생성합니다.)
[질문] 어떻게 하면 우선순위가 55 인것이 먼저 종료하게 하죠? (선점 , 병렬 수행)
------------------------------
실행 결과입니다.
maxium pri = 99
minium pri = 1
쓰레드 파라미터 , 상속, 우선순위 설정 완료
thread_routine 0 running at PR / 50
thread id = 0 / i = 0
thread id = 0 / i = 10000
thread id = 0 / i = 20000
thread id = 0 / i = 30000
thread id = 0 / i = 40000
thread id = 0 / i = 50000
thread id = 0 / i = 60000
thread id = 0 / i = 70000
thread id = 0 / i = 80000
thread id = 0 / i = 90000
thread id = 0 / i = 100000
thread id = 0 / i = 110000
thread id = 0 / i = 120000
thread id = 0 / i = 130000
thread id = 0 / i = 140000
thread id = 0 / i = 150000
thread id = 0 / i = 160000
thread id = 0 / i = 170000
thread id = 0 / i = 180000
thread id = 0 / i = 190000
thread_routine 1 running at PR / 55
thread id = 1 / i = 0
thread id = 1 / i = 10000
thread id = 1 / i = 20000
thread id = 1 / i = 30000
thread id = 1 / i = 40000
thread id = 1 / i = 50000
thread id = 1 / i = 60000
thread id = 1 / i = 70000
thread id = 1 / i = 80000
thread id = 1 / i = 90000
thread id = 1 / i = 100000
thread id = 1 / i = 110000
thread id = 1 / i = 120000
thread id = 1 / i = 130000
thread id = 1 / i = 140000
thread id = 1 / i = 150000
thread id = 1 / i = 160000
thread id = 1 / i = 170000
thread id = 1 / i = 180000
thread id = 1 / i = 190000
메인 종료
-----------------------------------
소스 코드입니다.
/* 컴파일 : gcc -o testpri testprie.c -lpthread
* 실행 명령어 : sodo ./testpri2 (ubuntu 환경 )
* 참고 페이지 : http://man.kldp.org/wiki/ManPage/pthread_setschedparam.3
* 참고 : pthread_setschedparam은 수퍼 유저 권한을 가지 사용자가 실행하여야한다.
*
*/
#include
#include
#include
#define THREADS 2
/*각 스레드를 나타내는 구조체 */
typedef struct thread_tag{
int index;
pthread_t id;
pthread_attr_t thread_attr;
} thread_t;
thread_t threads[THREADS];
int rr_min_priority,rr_max_priority;
/*쓰레드 실행 루틴 */
void *thread_routine (void * arg)
{
thread_t *self = (thread_t *) arg;
int my_policy; //현재 쓰레드의 스케줄링 정책 확인용
struct sched_param my_param; //현재 쓰레드의 파라미터값 확인용
int status;
int i;
//스케줄링 정책 파마리터 확인
status = pthread_getschedparam(self->id, &my_policy, &my_param);
if (status!= 0)
printf("error at geting sched param\n");
// 읽어온 쓰레드 정보 출력
printf("thread_routine %d running at %s / %d\n",
self->index,
(my_policy == SCHED_FIFO ? "FIFO"
: (my_policy == SCHED_RR ? "PR"
: (my_policy == SCHED_OTHER ? "OTHRER"
: "unknown"))),
my_param.sched_priority);
//작업 수행
for(i=0; i<10000*20;i++)
{ if ( i % 10000 ==0 )printf ("thread id = %d / i = %d\n",self->index, i);
}
}
int main( int argc, char *arg[])
{
struct sched_param thread_param;
int count, status;
int total_roof;
total_roof=0;
// 쓰레드 스케줄링 지원 여부 체크
#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) && !defined (sun)
//우선순위 최고값 최소값 확인
rr_max_priority = sched_get_priority_max(SCHED_RR);
printf("maxium pri = %d\n" , rr_max_priority);
rr_min_priority = sched_get_priority_min(SCHED_RR);
printf("minium pri = %d\n" , rr_min_priority);
for (count = 0; count < THREADS; count++)
{
//스케줄링 정책 셋팅
status = pthread_attr_setschedpolicy( &threads[count].thread_attr, SCHED_RR);
//스케줄링 우선 순위 설정 ( 우선 순위= (최고 +최소)/2 + count*5 )
thread_param.__sched_priority= ( rr_min_priority + rr_max_priority)/2 + count*5;
status = pthread_attr_setschedparam( &threads[count].thread_attr , &thread_param);
//스케줄링 상속 설정
status = pthread_attr_setinheritsched(&threads[count].thread_attr, PTHREAD_EXPLICIT_SCHED);
}
printf ("쓰레드 파라미터 , 상속, 우선순위 설정 완료\n");
#else
printf(" 쓰레드 스케줄링이 지원되지 않습니다\n");
#endif
//쓰레드 생성 및 실행
for(count = 0; count < THREADS ; count++)
{
threads[count].index = count;
status = pthread_create (
&threads[count].id, &threads[count].thread_attr,
thread_routine, (void *)&threads[count]);
if (status!= 0)
printf("error at creating thread/n");
}
//쓰레드 종료대기
for(count = 0; count < THREADS; count++)
{
status = pthread_join ( threads[count].id, NULL);
if (status!= 0)
printf("error at joying thread/n");
}
printf ("메인 종료\n");
return 0;
}
Thread 생명주기를 좀 길게 해 보시죠.
Thread 1이 실행되기도 전에 thread 0가 끝나는 것 아닌가요?
Thread 생명 주기를 5분으로 해도 같은 결과가 나와요 .
위에 예제는 결과 한 화면에 출려할려고 시간 적게 준것이고요 시간을 5분으로 줘도 thread0의 실행이 끝나야 thread1이 시작된답니다.
위에 예제 그냥 testprie.c 에 저장한후 컴파일하면 실행되는데 확인해 보셔도되고요 . 아참 이거 루트 권한 가지고 실행하셔야합니다.
RR로 thread 스케줄링이 되고 있었네요.
위에 소스에서 thread rutine을 while로 감싸고 쓰레드 50 에는 usleep(1000) 쓰레드 70에는 usleep(500)을 주었습니다.
-------------------------수정 코드------------------------------------
while(1){
for(i=0; i<10000*10;i++)
{ if ( i % 10000 ==0 )printf ("thread id = %d / i = %d\n",self->index, i);
}
if( self->index == 0 )usleep(1000);
else usleep(500);
}
-------------------------------------------------------------------------
아래 실행 결과를 보시면 처음에는 쓰레드 50이 먼저 실행되지면 일정 시간이 지나면 쓰레드 70에 50으로부터 자원을 선점 함을 볼수있습니다.
-----------------실행 결과-------------------------------------------------
mmaxium pri = 99
minium pri = 1
쓰레드 파라미터 , 상속, 우선순위 설정 완료
thread_routine 0 running at PR / 50
thread id = 0 / i = 0
thread id = 0 / i = 10000
thread id = 0 / i = 20000
thread id = 0 / i = 30000
thread id = 0 / i = 40000
thread id = 0 / i = 50000
thread id = 0 / i = 60000
thread id = 0 / i = 70000
thread id = 0 / i = 80000
thread id = 0 / i = 90000
thread id = 0 / i = 0
thread id = 0 / i = 10000
thread id = 0 / i = 20000
thread id = 0 / i = 30000
thread id = 0 / i = 40000
thread id = 0 / i = 50000
thread id = 0 / i = 60000
thread id = 0 / i = 70000
thread id = 0 / i = 80000
thread id = 0 / i = 90000
thread_routine 1 running at PR / 70
thread id = 1 / i = 0
thread id = 1 / i = 10000
thread id = 1 / i = 20000
thread id = 1 / i = 30000
thread id = 1 / i = 40000
thread id = 1 / i = 50000
thread id = 1 / i = 60000
thread id = 1 / i = 70000
thread id = 1 / i = 80000
thread id = 1 / i = 90000
thread id = 0 / i = 0
thread id = 0 / i = 10000
thread id = 0 / i = 20000
thread id = 1 / i = 0
thread id = 1 / i = 10000
thread id = 1 / i = 20000
thread id = 1 / i = 30000
thread id = 1 / i = 40000
thread id = 1 / i = 50000
thread id = 1 / i = 60000
thread id = 1 / i = 70000
thread id = 1 / i = 80000
thread id = 1 / i = 90000
thread id = 0 / i = 30000
thread id = 0 / i = 40000
thread id = 0 / i = 50000
thread id = 1 / i = 0
thread id = 1 / i = 10000
thread id = 1 / i = 20000
thread id = 1 / i = 30000
thread id = 1 / i = 40000
thread id = 1 / i = 50000
thread id = 1 / i = 60000
thread id = 1 / i = 70000
thread id = 1 / i = 80000
thread id = 1 / i = 90000
thread id = 0 / i = 60000
thread id = 0 / i = 70000
thread id = 1 / i = 0
thread id = 1 / i = 10000
thread id = 1 / i = 20000
thread id = 1 / i = 30000
thread id = 1 / i = 40000
thread id = 1 / i = 50000
thread id = 1 / i = 60000
thread id = 1 / i = 70000
thread id = 1 / i = 80000
thread id = 1 / i = 90000
thread id = 0 / i = 80000
thread id = 0 / i = 90000
thread id = 1 / i = 0
thread id = 1 / i = 10000
thread id = 1 / i = 20000
thread id = 1 / i = 30000
thread id = 1 / i = 40000
thread id = 1 / i = 50000
thread id = 1 / i = 60000
thread id = 1 / i = 70000
thread id = 1 / i = 80000
thread id = 1 / i = 90000
thread id = 0 / i = 0
thread id = 0 / i = 10000
thread id = 0 / i = 20000
thread id = 1 / i = 0
thread id = 1 / i = 10000
thread id = 1 / i = 20000
thread id = 1 / i = 30000
thread id = 1 / i = 40000
thread id = 1 / i = 50000
thread id = 1 / i = 60000
thread id = 1 / i = 70000
thread id = 1 / i = 80000
thread id = 1 / i = 90000
thread id = 0 / i = 30000
thread id = 0 / i = 40000
thread id = 0 / i = 50000
thread id = 1 / i = 0
thread id = 1 / i = 10000
thread id = 1 / i = 20000
-----------------------------------------------------------수정 코드 전체---------------------------------------------------
/* date : 08 07 06
* 컴파일 : gcc -o testpri testprie.c -lpthread
* 실행 명령어 : sodo ./testpri2 (ubuntu )
* 참고 페이지 : http://man.kldp.org/wiki/ManPage/pthread_setschedparam.3
* 참고 : pthread_setschedparam은 수퍼 유저 권한을 가지 사용자가 실행하여야한다.
* 문제 : 쓰레드간 선점이 일어 나지 않는거같다.
*/
#include
#include
#include
#define THREADS 2
/*각 스레드를 나타내는 구조체 */
typedef struct thread_tag{
int index;
pthread_t id;
pthread_attr_t thread_attr;
} thread_t;
thread_t threads[THREADS];
int rr_min_priority,rr_max_priority;
/*쓰레드 실행 루틴 */
void *thread_routine (void * arg)
{
thread_t *self = (thread_t *) arg;
int my_policy; //현재 쓰레드의 스케줄링 정책 확인용
struct sched_param my_param; //현재 쓰레드의 파라미터값 확인용
int status;
int i=0;
//스케줄링 정책 파마리터 확인
status = pthread_getschedparam(self->id, &my_policy, &my_param);
if (status!= 0)
printf("error at geting sched param\n");
// 읽어온 쓰레드 정보 출력
printf("thread_routine %d running at %s / %d\n",
self->index,
(my_policy == SCHED_FIFO ? "FIFO"
: (my_policy == SCHED_RR ? "PR"
: (my_policy == SCHED_OTHER ? "OTHRER"
: "unknown"))),
my_param.sched_priority);
//작업 수행
while(1){
for(i=0; i<10000*10;i++)
{ if ( i % 10000 ==0 )printf ("thread id = %d / i = %d\n",self->index, i);
}
if( self->index == 0 )usleep(1000);
else usleep(500);
//printf ("thread id = %d / i = %d\n",self->index, i);
//sleep(2);
}
}
int main( int argc, char *arg[])
{
struct sched_param thread_param;
int count, status;
int total_roof;
total_roof=0;
// 쓰레드 스케줄링 지원 여부 체크
#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) && !defined (sun)
//우선순위 최고값 최소값 확인
rr_max_priority = sched_get_priority_max(SCHED_RR);
printf("maxium pri = %d\n" , rr_max_priority);
rr_min_priority = sched_get_priority_min(SCHED_RR);
printf("minium pri = %d\n" , rr_min_priority);
for (count = 0; count < THREADS; count++)
{
//스케줄링 정책 셋팅
status = pthread_attr_setschedpolicy( &threads[count].thread_attr, SCHED_RR);
//스케줄링 우선 순위 설정 ( 우선 순위= (최고 +최소)/2 + count*5 )
thread_param.__sched_priority= ( rr_min_priority + rr_max_priority)/2 + count*20;
status = pthread_attr_setschedparam( &threads[count].thread_attr , &thread_param);
//스케줄링 상속 설정
status = pthread_attr_setinheritsched(&threads[count].thread_attr, PTHREAD_EXPLICIT_SCHED);
}
printf ("쓰레드 파라미터 , 상속, 우선순위 설정 완료\n");
#else
printf(" 쓰레드 스케줄링이 지원되지 않습니다\n");
#endif
//쓰레드 생성 및 실행
for(count = 0; count < THREADS ; count++)
{
threads[count].index = count;
status = pthread_create (
&threads[count].id, &threads[count].thread_attr,
thread_routine, (void *)&threads[count]);
if (status!= 0)
printf("error at creating thread/n");
}
//쓰레드 종료대기
for(count = 0; count < THREADS; count++)
{
status = pthread_join ( threads[count].id, NULL);
if (status!= 0)
printf("error at joying thread/n");
}
printf ("메인 종료\n");
return 0;
}
...
원인은 policy가 RR이기도 하지만, RT프로세스로 수행이 되고 있기 때문입니다.
SCHED_RR : RT 프로세스
SCHED_FIFO : RT 프로세스
SCHED_OTHER(NORMAL) : 일반 프로세스
SCHED_BATCH : 일반 프로세스
처음 예제에서 '우선순위:50'이 수행되는 구간에서는 '우선순위:55' 프로세스는 생성조차 되지 않습니다.
RT 프로세스는 일반 프로세스보다 무조건 우선순위가 높으며 따라서 일반 프로세스에 의해서는 선점 되지 않습니다.
따라서, 우선순위:50 프로세스는 수행됨과 동시에 main 프로세스의 수행을 막아 우선순위:55 프로세스의 생성을 막게 됩니다.
(이것은 몇 시간이 되었건 '우선순위:50' 프로세스가 수행되는 동안에는 그렇습니다.)
참고로, RR이나 FIFO 은 동일한 우선순위를 갖는 프로세스에서 적용 되는 규칙입니다.
댓글 달기