Управление процессами и нитями в ОС QNX. Основные принципы управления процессами и нитями в ОС QNX, страница 13

Дисциплина планирования RR, 0 процесс занял все процессорное время.

Анализ дисциплины планирования для нитей в рамках одного процесса.

thr_schedule.c

#include <stdlib.h>

#include <stdio.h>

#include <sched.h>

#include <sys/types.h>

#include <process.h>

#include <string.h>

#include <errno.h>

#include <sys/mman.h>

#include <fcntl.h>

#include <unistd.h>

#include <sys/stat.h>

#include <pthread.h>

#define SIZE 32000

char *buffer;

int position;

pthread_attr_t attr_th0, attr_th1;

void* thread0 ( void* ptr)

{    

int j;

struct sched_param sp;

pthread_attr_getschedparam(&attr_th0, &sp);

printf("thread0: policy = %i\tpriority = %i\n", sched_getscheduler(0), sp.sched_priority);

sleep(1);

while(position < SIZE)

{    

for (j=0; j<2000; j++);

*(buffer + position) = '0';

position++;

}

pthread_exit(NULL);

}

void* thread1 ( void* ptr)

{

int j;

struct sched_param sp;

pthread_attr_getschedparam(&attr_th1, &sp);

printf("thread1: policy = %i\tpriority = %i\n", sched_getscheduler(0), sp.sched_priority);

sleep(1);

while(position < SIZE)

{    

for (j=0; j<2000; j++);

*(buffer + position) = '1';

position++;

}

pthread_exit(NULL);

}

int main( int argc, char *argv[])

{

int i, policy, fd;

char argum[5];

struct sched_param param, tr0, tr1;

pthread_t thr0, thr1;

if(argc<3)

{

fprintf(stderr, " Need %s  policy priority_of_threads\n", argv[0]);

return EXIT_FAILURE; 

}

policy = atoi(argv[1]);

sched_getparam(0, &param);

param.sched_priority = 20;

sched_setscheduler(0, policy, &param);

sched_getparam(0, &tr0);

tr0.sched_priority = atoi(argv[2]);

sched_getparam(0, &tr1);

tr1.sched_priority = atoi(argv[3]);

//create a new memory object for data array

fd = shm_open("buffer", O_RDWR | O_CREAT, 0777);

if (fd ==-1)

{

fprintf(stderr, "shm_open: open failed: %s\n", strerror(errno));

return EXIT_FAILURE;

}

//set the memory object's size

if(ftruncate(fd, SIZE) == -1)

{

fprintf(stderr, "ftruncate: %s\n", strerror(errno));

return EXIT_FAILURE;

}

//map the memory object

buffer = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

if( buffer == MAP_FAILED)

{

fprintf(stderr, "mmap failed: %s\n", strerror(errno));

return EXIT_FAILURE;

}

position = 0;

pthread_attr_init(&attr_th0);

pthread_attr_setinheritsched(&attr_th0, PTHREAD_EXPLICIT_SCHED);

pthread_attr_setschedparam(&attr_th0, &tr0);

pthread_attr_init(&attr_th1);

pthread_attr_setinheritsched(&attr_th1, PTHREAD_EXPLICIT_SCHED);

pthread_attr_setschedparam(&attr_th1, &tr1);

pthread_create(&thr0, &attr_th0, thread0, NULL);

pthread_create(&thr1, &attr_th1, thread1, NULL);

system("ps -l");

pthread_join(thr0, NULL);

pthread_join(thr1, NULL);

printf("\n%s\n", buffer);

shm_unlink("buffer");

return EXIT_SUCCESS;

}    

Пользователь задает приоритеты двух нитей и политику их диспетчеризации. Каждая из этих нитей пытается записать свой порядковый номер в общую область разделяемой памяти, при этом указатель на крайнюю свободную ячейку также общий. Таким образом, по окончании работы программы мы сможем по содержимому памяти проследить за очередностью работы нитей.

В структурах-аргументах нитей выставлен флаг PTHREAD_EXPLICIT_SCHED, который позволяет применять к нитям настройки диспетчеризации, отличные от настроек процессора

Пример работы программы:

./thr_schedule 1 45 56

F S UID  PID     PPID   C PRI NI ADDR  SZ WCHAN TTY     TIME CMD

00000000 -  0  6434561  577345 -  20 0    - 892K -     ?   00:00:00 ./thr_schedule

00000000 -  0  6434561  577345  - 45 0    - 892K -     ?   00:00:00 ./thr_schedule