Как приостановить/возобновить потоки в OmniThreadLibrary 3?

Я хочу, чтобы основной поток приложения мог приостанавливать/возобновлять другие рабочие потоки, если это возможно, как лучше всего это сделать?

Любое предложение, которое будет работать в Windows XP (и более поздних версиях), будет более чем приветствоваться!

PS. Я использую Delphi 2010 и OmniThreadLibrary 3.


person TheDude    schedule 02.09.2012    source источник
comment
Вы никогда не приостанавливаете потоки извне. Основной поток сообщает, что он хочет приостановить поток, а затем отвечает, ожидая, пока он не получит сигнал о возобновлении.   -  person David Heffernan    schedule 02.09.2012
comment
Пример того, как это сделать с сигналом события (хотя и не с инфраструктурой OTL), см. в разделе Нужен ли мне TThreads? Если да, могу ли я приостановить, возобновить и остановить их?.   -  person LU RD    schedule 02.09.2012
comment
Спасибо, ребята, за вашу помощь / ссылку. Я считаю, что можно сделать паузу извне, я надеюсь посмотреть, есть ли безопасный/рекомендуемый способ сделать это в OTL.   -  person TheDude    schedule 02.09.2012
comment
Если вы приостановите его извне и если ваш поток использует какие-либо блокировки, вы можете зайти в тупик. Вам нужно будет пересмотреть свои ожидания. Прочтите, например, документы Windows API для SuspendThread.   -  person David Heffernan    schedule 02.09.2012


Ответы (1)


OmniThreadLibrary не предоставляет команд для приостановки потока. Метод API для приостановки потока заключается в вызове SuspendThread, и эта функция вызывается только в двух местах, ни одно из которых не доступно для прямого использования вне библиотеки.

Если у вас есть TOTPWorkerThread, вы можете вызвать SuspendThread в его свойстве Handle.

Не существует безопасного рекомендуемого способа приостановки потока вне его собственного контекста. Это неизменно приводит к проблемам, потому что внешний поток не может точно знать, что делает другой поток в тот момент, когда он пытается его приостановить. Он может находиться в середине оператора ввода-вывода или может удерживать блокировку, которую ожидают другие потоки.

Безопасный и рекомендуемый способ приостановить поток — отправить ему какое-либо уведомление о том, что вы хотите, чтобы он приостановил сам себя. В контексте OmniThreadLibrary это может означать вызов Cancel в рабочем потоке.

Лучший способ приостановить поток — не приостанавливать его вообще. Обычный случай приостановки потока заключается в том, что ему больше нечего делать в данный момент, поэтому, когда что-то становится доступным, вы хотите разбудить его, чтобы он мог продолжить обработку новой работы. Однако вы можете сделать это без приостановки. Вместо этого заставьте поток ожидать в очереди, содержащей рабочие элементы. В OmniThreadLibrary для этого есть несколько механизмов. Вы можете поместить каждую единицу работы в отдельную задачу, а затем поместить эти задачи в пул потоков. Вы также можете поместить свои задачи в простую очередь, а затем сделать так, чтобы в очереди работал один поток.

person Rob Kennedy    schedule 02.09.2012
comment
Я думаю, что демонстрация OTL 05_TwoWayHello_without_loop является хорошей отправной точкой. - person Edwin Yip; 30.10.2012