CWinThread Inquiries (MFC) - PullRequest
       15

CWinThread Inquiries (MFC)

1 голос
/ 09 марта 2011

У меня очень простой вопрос о том, как работает CWinThread и где находится точка входа каждый раз, когда я вызываю ResumeThread (). Я ищу запись, которая выглядит как «основная» функция, где я могу выполнять некоторые операции и ветки.

Мне также интересно, как завершить или убить запущенные потоки в любой точке из другого потока. Где я должен положить AfxEndThread ()? или просто вызовите pThread-> ExitInstance ()?

Мой последний вопрос: если я хочу создать несколько потоков, как мне организовать их в Стандартной библиотеке шаблонов (STL) с использованием вектора?

Спасибо.

Ответы [ 2 ]

2 голосов
/ 09 марта 2011

Я думаю, у вас есть фундаментальное неправильное понимание того, как предполагается использовать потоки.

Такие функции, как SuspendThread() и ResumeThread() и функции для завершения потоков, не предназначены для управления потоками. Фактически функции Windows API, на которые отображаются SuspendThread() и ResumeThread(), задокументированы как предназначенные для отладчиков. Было бы неплохо, если бы в документации MFC об этом говорилось, но это не так.

Если вы используете SuspendThread() для приостановки потока, тогда вы не представляете, что он делает, когда приостанавливаете его. Если случается, что блокировка удерживается, вы можете заблокировать вашу программу.

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

Что касается терминации, это абсолютно последнее средство, чтобы позвонить TerminateThread(). Это оставляет ваши объекты синхронизации (например, критические секции, мьютексы и т. Д.) В неопределенном состоянии и с большой вероятностью приведет к ужасным дефектам в вашем программном обеспечении. Снова для завершения вы должны сообщить потоку, что вы хотите, чтобы он вышел, и затем подождать, пока это не будет сделано.

1 голос
/ 09 марта 2011

Основной точкой входа для класса, производного от CWinThread, является виртуальная функция Run().Однако, есть также функция InitInstance(), которая вызывается заранее, и функция ExitInstance(), вызываемая впоследствии.

Вы никогда не должны вызывать ExitInstance() самостоятельно.Вместо этого вызовите AfxEndThread или просто вернитесь с Run().

Если вы действительно хотите поместить свои потоки в std::vector<>, тогда используйте указатель, поскольку класс не подлежит копированию, а экземпляр удаляетсяавтоматически MFC при выходе из потока.

Редактировать: Как отметил Дэвид, вы обычно не хотите использовать SuspendThread и ResumeThread в коде приложения.Начните тему с AfxBeginThread, если вы используете MFC.

...