Мобильное программирование приложений реального времени в стандарте POSIX

pid_t pid, int policy, const


#include <sched.h>
int sched_getscheduler (pid_t pid);
int sched_getparam (pid_t pid, struct sched_param *param);
int sched_setscheduler ( pid_t pid, int policy, const struct sched_param *param);
int sched_setparam (pid_t pid, const struct sched_param *param);
Листинг 6.1. Описание функций управления планированием.
Закрыть окно




#include <sched.h>
int sched_get_priority_min (int policy);
int sched_get_priority_max (int policy);
int sched_rr_get_interval (pid_t pid, struct timespec *q_ptr);


Листинг 6.2. Описание функций опроса характеристик политик планирования.
Закрыть окно




#include <sched.h> int sched_yield (void);
Листинг 6.3. Описание функции sched_yield().
Закрыть окно




/* * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Программа опрашивает характеристики политик планирования, */ /* а также атрибуты планирования текущего процесса */ /* * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <stdio.h> #include <sched.h>
int main (void) { struct sched_param shdprm; /* Значения параметров */ /* планирования */ struct timespec qp; /* Величина кванта */ /* процессорного времени */
printf ("Допустимые диапазоны приоритетов для разных " "политик планирования\n"); printf ("SCHED_FIFO : от %d до %d\n", sched_get_priority_min (SCHED_FIFO), sched_get_priority_max (SCHED_FIFO)); printf ("SCHED_RR : от %d до %d\n", sched_get_priority_min (SCHED_RR), sched_get_priority_max (SCHED_RR)); printf ("SCHED_OTHER: от %d до %d\n", sched_get_priority_min (SCHED_OTHER), sched_get_priority_max (SCHED_OTHER));
printf ("Текущая политика планирования для текущего " "процесса: "); switch (sched_getscheduler (0)) { case SCHED_FIFO: printf ("SCHED_FIFO\n"); break; case SCHED_RR: printf ("SCHED_RR\n"); break; case SCHED_OTHER: printf ("SCHED_OTHER\n"); break; case -1: perror ("SCHED_GETSCHEDULER"); break; default: printf ("Неизвестная политика планирования\n"); }
if (sched_getparam (0, &shdprm) == 0) { printf ("Текущий приоритет текущего процесса: %d\n", shdprm.sched_priority); } else { perror ("SCHED_GETPARAM"); }
shdprm.sched_priority = 50; if (sched_setscheduler (0, SCHED_RR, &shdprm) == -1) { perror ("SCHED_SETSCHEDULER"); }
if (sched_rr_get_interval (0, &qp) == 0) { printf ("Квант процессорного времени при " "циклическом планировании: %g сек\n", qp.tv_sec + qp.tv_nsec / 1000000000.0);
} else { perror ("SCHED_RR_GET_INTERVAL"); }
return 0; }
Листинг 6.4. Пример программы, использующей функции управления планированием.
Закрыть окно




Допустимые диапазоны приоритетов для разных политик планирования
SCHED_FIFO : от 1 до 99 SCHED_RR : от 1 до 99 SCHED_OTHER : от 0 до 0
Текущая политика планирования для текущего процесса: SCHED_OTHER Текущий приоритет текущего процесса: 0 Квант процессорного времени при циклическом планировании: 0.15 сек
Листинг 6.5. Возможные результаты выполнения программы, использующей функции управления планированием, в ОС Linux.
Закрыть окно




Допустимые диапазоны приоритетов для разных политик планирования SCHED_FIFO : от 1 до 255 SCHED_RR : от 1 до 255 SCHED_OTHER : от 0 до 255 Текущая политика планирования для текущего процесса: SCHED_FIFO Текущий приоритет текущего процесса: 100 Квант процессорного времени при циклическом планировании: 0.08 сек
Листинг 6.6. Возможные результаты выполнения программы, использующей функции управления планированием, в операционной системе реального времени oc2000.
Закрыть окно




/* * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Программа моделирует ситуацию инверсии приоритетов. */ /* Идея состоит в том, что имеется три потока */ /* управления с низким, средним */ /* и высоким приоритетами. */ /* Поток с низким приоритетом захватывает семафор, */ /* когда на него никто больше не претендует, */ /* но не может освободить его, */ /* потому что его вытесняет с процессора */ /* поток со средним приоритетом. */ /* В это время поток с высоким приоритетом хочет */ /* захватить тот же семафор, */ /* но он занят и неизвестно когда освободится... */ /* * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <stdio.h> #include <pthread.h> #include <sched.h> #include <semaphore.h> #include <assert.h>
static sem_t sem_mi; /* Семафор для потока со средним */ /* приоритетом */ static sem_t sem_hi; /* Семафор для потока с высоким */ /* приоритетом */
static double s = 0;
/* * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Стартовая функция потока с высоким приоритетом */ /* * * * * * * * * * * * * * * * * * * * * * * * * * */ void *start_hi (void *dummy) { printf ("Поток с высоким приоритетом перед захватом " "семафора\n"); assert (sem_wait (&sem_hi) == 0); printf ("Поток с высоким приоритетом после захвата " "семафора\n"); assert (sem_post (&sem_hi) == 0);
return (NULL); }
/* * * * * * * * * * * * * * * * * * * * * * * * * */ /* Стартовая функция потока со средним приоритетом */ /* * * * * * * * * * * * * * * * * * * * * * * * * */ void *start_mi (void *dummy) { int i; double d = 1;
printf ("Поток со средним приоритетом перед захватом " "семафора\n"); assert (sem_wait (&sem_mi) == 0); /* Займем процессор вычислениями */ for (i = 1; i < 100000000; i++) { s += d/i; d = -d; } printf ("Поток со средним приоритетом перед " "освобождением семафора\n"); assert (sem_post (&sem_mi) == 0);
return (&s); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Стартовая функция потока с низким приоритетом */ /* * * * * * * * * * * * * * * * * * * * * * * * * * */ int main (void) { pthread_attr_t attrob; /* Атрибутный объект */ /* создаваемых потоков */ struct sched_param shdprm; /* Значения параметров */ /* планирования */ int shdplc; /* Политика планирования */ pthread_t pt_mi; /* Идентификатор потока */ /* со средним приоритетом */ pthread_t pt_hi; /* Идентификатор потока */ /* с высоким приоритетом */
/* Создадим два семафора в захваченном состоянии */ assert (sem_init (&sem_mi, 0, 0) == 0); assert (sem_init (&sem_hi, 0, 0) == 0);
/* Установим политику планирования и сделаем */ /* текущий поток управления низкоприоритетным */ shdprm.sched_priority = sched_get_priority_max (SCHED_FIFO) – 31; assert (pthread_setschedparam (pthread_self (), SCHED_FIFO, &shdprm) == 0);
/* Инициализируем атрибутный объект */ /* для создаваемых потоков управления */ assert (pthread_attr_init (&attrob) == 0);
/* Установим атрибуты планирования */ assert (pthread_attr_setinheritsched (&attrob, PTHREAD_EXPLICIT_SCHED) == 0); assert (pthread_attr_setschedpolicy (&attrob, SCHED_FIFO) == 0); shdprm.sched_priority += 15; assert (pthread_attr_setschedparam (&attrob, &shdprm) == 0);
/* Создадим поток управления со средним приоритетом */ assert (pthread_create (&pt_mi, &attrob, start_mi, NULL) == 0);
/* Подправим атрибутный объект и создадим */ /* поток управления с высоким приоритетом */ shdprm.sched_priority += 15; assert (pthread_attr_setschedparam (&attrob, &shdprm) == 0); assert (pthread_create (&pt_hi, &attrob, start_hi, NULL) == 0);
/* Опросим параметры планирования потоков управления */ assert (pthread_getschedparam (pthread_self (), &shdplc, &shdprm) == 0); assert (shdplc == SCHED_FIFO); printf ("Низкий приоритет: %d\n", shdprm.sched_priority); assert (pthread_getschedparam (pt_mi, &shdplc, &shdprm) == 0); assert (shdplc == SCHED_FIFO); printf (&quot;Средний приоритет: %d\n", shdprm.sched_priority); assert (pthread_getschedparam (pt_hi, &shdplc, &shdprm) == 0); assert (shdplc == SCHED_FIFO); printf ("Высокий приоритет: %d\n", shdprm.sched_priority);
/* Создадим ситуацию инверсии приоритетов */ printf ("Поток с низким приоритетом\n" "перед освобождением семафора для потока " "со средним приоритетом\n"); assert (sem_post (&sem_mi) == 0);
printf ("Поток с низким приоритетом\n" "перед освобождением семафора для потока " "с высоким приоритетом\n"); assert (sem_post (&sem_hi) == 0);
(void) pthread_join (pt_mi, NULL); (void) pthread_join (pt_hi, NULL);
assert (sem_destroy (&sem_mi) == 0); assert (sem_destroy (&sem_hi) == 0);
return 0; }
Листинг 6.7. Пример программы, моделирующей ситуацию инверсии приоритетов.
Закрыть окно




Поток со средним приоритетом перед захватом семафора Поток с высоким приоритетом перед захватом семафора Низкий приоритет: 224 Средний приоритет: 239 Высокий приоритет: 254 Поток с низким приоритетом перед освобождением семафора для потока со средним приоритетом Поток со средним приоритетом перед освобождением семафора Поток с низким приоритетом перед освобождением семафора для потока с высоким приоритетом Поток с высоким приоритетом после захвата семафора
Листинг 6.8. Возможные результаты выполнения программы, моделирующей ситуацию инверсии приоритетов, под управлением операционной системы реального времени oc2000.
Закрыть окно



Содержание раздела