Valor de prioridade personalizado: é um prio de agendamento alto pthread positivo ou negativo?

0

Estou tentando reimplementar de maneira compatível com versões anteriores a API do RobotC de C (embora alguns detalhes sejam mais adequados ou mais fáceis com o C ++) e tentando para reimplementar sua API multithreading de alguma maneira portável, então eu tento usar sched_get_priority_max(2) e %código%. Mas, por um lado, sched_get_priority_min(2) e nice(1) dizem que a prioridade está entre -20 (prioridade mais alta) e 19 (menor prioridade), por outro lado, as antigas páginas man afirmavam que:

[…] numerically higher priority values are scheduled before processes with numerically lower priority values. Thus, the value returned by sched_get_priority_max() will be greater than the value returned by sched_get_priority_min()

que significaria o oposto: valor positivo é de prioridade mais alta e negativo de prioridade mais baixa (também dá o exemplo de políticas em tempo real onde a prioridade é entre 1 e 99).

O que será retornado por sched(7) e sched_get_priority_max ? o que devo usar com _min ?

Eu tenho três valores que definem meu intervalo de prioridade personalizado: a baixa prioridade ( pthread_attr_setschedparam(3) , definida como 0), a alta ( kLowPriority , definida como 255) e a padrão ( kHighPriority , definida como 7 ). Idealmente, suponho que o padrão seja 0 para as políticas de agendamento com um padrão, kDefaultPriority / 7 deve se tornar 0, kDefaultPriority / 255 a prioridade mais alta (19? 99? O que quer que kHighPriority retorne) ou talvez a mais alta prioridade ser atribuído se unpriviledged? e, em seguida, sched_get_priority_max(3) kLowPriority , a prioridade mais baixa ... qual seria a mais razoável?

Atualmente, acho que faço assim:

pthread_attr_t attr;
pthread_t thread;
struct sched_param param;
const int policy = sched_getscheduler(0),
  sched_high_prio = sched_get_priority_max(policy), // 19,
  sched_low_prio = sched_get_priority_min(policy), // -20,
  sched_range_prio = sched_high_prio - sched_low_prio;
pthread_attr_init (&attr);
pthread_attr_getinheritsched(&attr, PTHREAD_INHERIT_SCHED);
pthread_attr_getschedparam (&attr, &param);
param.sched_priority = -(((nTaskPriority
                           - kLowPriority) * sched_range_prio
                          / kHighPriority) + sched_low_prio
                         - kDefaultTaskPriority);

PS: Não tenho certeza se o melhor lugar para fazer essa pergunta sobre a API POSIX é aqui ou stackoverflow , por isso estou fazendo as duas coisas, por favor, apague meu post ou peça-me para excluir se você acha que está no lugar errado. EDIT: SO postar excluído.

    
por galex-713 25.03.2018 / 05:39

1 resposta

0

Acho que você está procurando uma resposta portátil, mas um bom começo para entender isso é olhar para o comportamento no Linux, conforme documentado na manpage para sched(7) , na seção" Políticas de agendamento ":

The scheduler is the kernel component that decides which runnable thread will be executed by the CPU next. Each thread has an associated scheduling policy and a static scheduling priority, sched_priority. The scheduler makes its decisions based on knowledge of the scheduling policy and static priority of all threads on the system.

For threads scheduled under one of the normal scheduling policies (SCHED_OTHER, SCHED_IDLE, SCHED_BATCH), sched_priority is not used in scheduling decisions (it must be specified as 0).

Processes scheduled under one of the real-time policies (SCHED_FIFO, SCHED_RR) have a sched_priority value in the range 1 (low) to 99 (high). (As the numbers imply, real-time threads always have higher priority than normal threads.) Note well: POSIX.1 requires an implementation to support only a minimum 32 distinct priority levels for the real-time policies, and some systems supply just this minimum. Portable programs should use sched_get_priority_min(2) and sched_get_priority_max(2) to find the range of priorities supported for a particular policy.

Veja também a documentação do POSIX para pthread_setschedparam , que requer apenas três políticas ( SCHED_OTHER , SCHED_FIFO e SCHED_RR ) e declara que o comportamento sob o primeiro é definido pela implementação.

Portanto, se você deseja agendar threads usando uma prioridade, portably, você precisa usar a política apropriada primeiro (FIFO ou round-robin). Em seguida, você determina o intervalo de valores e define a prioridade conforme apropriado. Encadeamentos e processos são agendados por prioridade decrescente: encadeamentos com prioridade mais alta serão executados primeiro.

No Linux, o comportamento padrão (implementação definida por POSIX) usa uma prioridade dinâmica que é calculada com base no valor nice e com que frequência um determinado segmento é não agendado. No Linux, o valor nice determina a prioridade menor primeiro, então -20 é a prioridade mais alta, 19 a mais baixa. POSIX descreve nice como um valor por processo, mas no Linux é por thread, então você pode usar para agendar threads lá (mas isso não é portátil).

    
por 25.03.2018 / 15:40