Перейти к содержанию
Fire Monkey от А до Я
  • 0

Как правильно назначить TThread Policy and Priority в Linux


Sergey S

Вопрос

Добрый день всем.

Подскажите пожалуйста, как правильно назначить приоритет создаваемому потоку для Linux (RAD Studio 11.2)?

Пробовал так:

constructor TMyThread.Create;
begin
   inherited Create(True);

   Policy   := 1;
   Priority := 90;
end;

После инициализации потока приложение "падает" с ошибкой: Thread error: Недопустимый аргумент (22). Если просто запустить поток по умолчанию, все работает.

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

Для установки приоритета потока в Linux в Delphi можно использовать функцию pthread_setschedparam(). Эта функция позволяет задать приоритет потока в соответствии с POSIX-стандартом.

Пример использования функции pthread_setschedparam() для установки приоритета потока можно найти в следующем коде:

uses
  Posix.Sched;

var
  Params: sched_param;
  ThreadId: pthread_t;
begin
  ThreadId := pthread_self();
  Params.sched_priority := 10; // устанавливаем приоритет 10
  if pthread_setschedparam(ThreadId, SCHED_FIFO, @Params) <> 0 then
    raise Exception.Create('Error setting thread priority');
end;

В этом примере мы устанавливаем приоритет потока на уровне 10 с помощью структуры sched_param. Далее мы используем функцию pthread_setschedparam() для установки приоритета нашему потоку, и если функция возвращает значение отличное от 0, то возникает исключение.

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

Ссылка на комментарий
  • 0

Спасибо Вам большое, все получилось, но пришлось код немного подправить.

1. В раздел USES добавить модуль Posix.Pthread, функции pthread_self и pthread_setschedparam определены как раз в нем

2. Тип pthread_t, я так понял, в RAD Studio отсутствует (скорее всего он из Си). Заменил его на LongWord (тип функции pthread_self).

3. При вызове функции pthread_setschedparam аргумент Params передается непосредственно, а не через указатель.

Исправленный код:

uses
  Posix.Sched, Posix.Pthread;

var
  Params: sched_param;
  ThreadId: LongWord;
begin
  ThreadId := pthread_self();
  Params.sched_priority := 10; // устанавливаем приоритет 10
  if pthread_setschedparam(ThreadId, SCHED_FIFO, Params) <> 0 then
    raise Exception.Create('Error setting thread priority');
end;

И последнее. Чтобы все корректно работало, приложение необходимо запускать с root правами. Иначе вызов pthread_setschedparam вернет ошибку 1, и никакой приоритет не установится.

Ссылка на комментарий
  • 0

Вот обновленный и адаптированный вариант вашего кода для изменения приоритета потока на платформе POSIX в Delphi:

uses
  Posix.Sched, Posix.Pthread, Posix.Errno;

procedure SetThreadPriority;
var
  Params: sched_param;
  ThreadId: pthread_t;
  Res: Integer;
begin
  ThreadId := pthread_self();
  Params.sched_priority := 10; // устанавливаем приоритет 10
  Res := pthread_setschedparam(ThreadId, SCHED_FIFO, @Params);
  if Res <> 0 then
    raise Exception.CreateFmt('Error setting thread priority: %d', [Res]);
end;

Вы правильно указали, что для изменения приоритета потока может потребоваться выполнение приложения с правами администратора (root). Если ваше приложение должно работать без таких прав, убедитесь, что вы обрабатываете ошибки, возникающие при изменении приоритета, и рассмотрите возможность использования альтернативных методов изменения приоритета или оптимизации производительности.

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

Ссылка на комментарий
  • 0

Спасибо большое Вам за уточнение!

Не могли бы Вы пояснить некоторые моменты.

1. По какой причине в данном случае подключается модуль Posix.Errno? В коде к нему обращения нет.

2. Тип pthread_t в RAD Studio не определен (у меня версия 11.2). Каким образом Вам удалось заставить компилироваться данный код?

3. Код pthread_setschedparam(ThreadId, SCHED_FIFO, @Params) так же не компилируется, потому что функция pthread_setschedparam в RAD Studio в качестве аргумента Params требует передавать значение, а не указатель на него. Я так думаю, здесь , как и в п.2, скорее всего взято из Си.

Спасибо.

Ссылка на комментарий
  • 0
  1. Вероятно, модуль Posix.Errno был подключен по ошибке или случайно. Действительно, в коде нет обращения к этому модулю, и он не является необходимым в данном случае. Вы можете удалить его из списка используемых модулей без воздействия на функциональность кода.

  2. Моя изначальная ошибка заключается в том, что я не учел особенности синтаксиса и типов данных RAD Studio (Delphi) при написании кода. В RAD Studio тип pthread_t действительно не определен. Вам нужно использовать тип TThreadID из модуля System.Types для совместимости с Delphi:

  3. uses
      Posix.Sched, Posix.Pthread;
    
    procedure SetThreadPriority;
    var
      Params: sched_param;
      ThreadId: TThreadID;
      Res: Integer;
    begin
      ThreadId := GetCurrentThreadId();
      Params.sched_priority := 10; // устанавливаем приоритет 10
      Res := pthread_setschedparam(ThreadId, SCHED_FIFO, Params);
      if Res <> 0 then
        raise Exception.CreateFmt('Error setting thread priority: %d', [Res]);
    end;

     

  4. Моя изначальная ошибка в коде заключается в передаче аргумента Params как указателя. В RAD Studio (Delphi) функция pthread_setschedparam принимает значение, а не указатель на него. Вы можете исправить эту ошибку, передавая Params без оператора адреса (@), как показано в исправленном коде выше.
Ссылка на комментарий
  • 0

Спасибо Вам за уточнение.

Последнее замечание наверное. При таком вызове:

ThreadId := GetCurrentThreadId();

Процедура SetThreadPriority должна вызываться непосредственно из потока, приоритет которого мы собираемся менять. Если стоит задача например из главного потока изменить приоритет другого потока, который был создан из главного, то такой способ здесь уже не подойдет. В данном случае необходимо будет воспользоваться свойством ThreadId класса TThread.

ThreadId:=SecondThread.ThreadId;
Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...