본문 바로가기

Enginius/Linux

[프로그래밍] 다른 NICE값을 갖는 쓰레드 만들기

리눅스에서는nice값을 이용해서 user-level thread를 관리한다. 
 -20~20 의 값을 갖고 낮을 수록 더 많은 시간을 할당받는다. niceness라는 단어는 이 값이 클 수록 다른 task를 많이 허용한다는 의미로 이해될 수 있다. 이 값과는 별개로 priority라는 값이 있는데 이 값은 높을수록 더 많은 시간을 할당받는다. ? 
 일반적으로 nice값이 5차이 날 때마다 weight값이 3배씩 차이가 나서 실제로 할당받는 시간이 3배 차이가 난다.  

#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>

static const int prio_to_weight[40] = {
 /* -20 */     88761,     71755,     56483,     46273,     36291,
 /* -15 */     29154,     23254,     18705,     14949,     11916,
 /* -10 */      9548,      7620,      6100,      4904,      3906,
 /*  -5 */      3121,      2501,      1991,      1586,      1277,
 /*   0 */      1024,       820,       655,       526,       423,
 /*   5 */       335,       272,       215,       172,       137,
 /*  10 */       110,        87,        70,        56,        45,
 /*  15 */        36,        29,        23,        18,        15,
};

#define N_CPUS 2
#define N_TASKS 6
static int test_nice[N_TASKS] = {
5, 5, 5, 5, 10,
10
};

static int test_tid[N_TASKS];
pthread_t test_pthread[N_TASKS];

static unsigned long get_vrt(int idx)
{
int i,j=0;
char buf[256];
int fd;
float vrt_f;
unsigned long vrt;
int tid;

tid = test_tid[idx];
snprintf(buf, 64, "/proc/%d/sched", tid);
fd = open(buf, O_RDONLY);
if(fd<0) {
perror("get_vrt");
exit(0);
}
read(fd, buf, 256);
buf[255]='\0';

for(i=0; i<3; i++)
while(buf[j++]!=':') {}

sscanf(buf+j, "%f", &vrt_f);
vrt = vrt_f * 1000000; // in usec
return vrt;
}

static void *test_func(void *arg)
{
long n = (long)arg;
// test_tid[n] = syscall(SYS_gettid);
while(1) {}
return NULL;
}

static void run_test(void)
{
long i;
printf("*** Creating task set ***\n");
for(i=0; i<N_TASKS; i++) {
test_tid[i] = 0;
setpriority(PRIO_PROCESS, test_tid[i], test_nice[i]);
pthread_create(test_pthread+i, NULL, test_func, (void *)i);
// while(!test_tid[i])
// sched_yield();
}
}

static void exit_test(void)
{
int i;
for(i=0; i<N_TASKS; i++)
pthread_join(test_pthread[i], NULL);
}

int main(int argc, char **argv)
{
int i;
run_test();
exit_test();
return 0;
}