Как блокировка процесса применяется к многопоточному процессу?

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

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

Я могу легко представить блокировку процесса, если он однопоточный или следует модели «один ко многим», но как это работает, если процесс многопоточный?

Например:

У меня есть процесс с двумя потоками в системе, которая следует модели один к одному. Один обрабатывает графический интерфейс, а другой — блокирующий ввод-вывод. Я знаю, что процесс остается отзывчивым, потому что другой поток обрабатывает ввод-вывод.

Так есть ли шанс, что процесс блокируется, или я должен просто исключить это в этом случае?

Я только начинаю вникать в эти вещи, так что простите меня, если я еще не понял некоторых важных деталей.


person ccnaflic    schedule 07.08.2013    source источник
comment
На этот вопрос будет сложно ответить без более конкретного контекста - могут быть огромные различия в зависимости от платформы, операционной системы, системных библиотек, языка программирования и поддерживаемой модели (моделей) многопоточности/обработки...   -  person twalberg    schedule 07.08.2013
comment
Извините, если я не могу получить более подробную информацию. Есть еще много вещей, с которыми я не знаком.   -  person ccnaflic    schedule 08.08.2013


Ответы (1)


Допустим, у вас есть рабочая очередь, в которой поток пользовательского интерфейса планирует выполнение работы, а поток ввода-вывода ищет там работу, которую нужно выполнить. Сама рабочая очередь — это данные, которые считываются и изменяются из обоих потоков, поэтому вы должны как-то синхронизировать доступ, иначе возникнут условия гонки.

Наивный подход — синхронизировать доступ к очереди с помощью блокировки (она же критическая секция). Если поток ввода-вывода получает блокировку, а затем блокируется, поток пользовательского интерфейса будет реагировать только до тех пор, пока не решит, что ему нужно запланировать работу, и не попытается получить блокировку. Лучшим подходом является использование очереди без блокировки, о которой много написано, и вы можете легко найти дополнительную информацию.

Но чтобы ответить на ваш вопрос, да, все же намного проще, чем вы думаете, заставить пользовательский интерфейс заикаться / зависать даже при использовании нескольких потоков. Существуют различные библиотеки, которые упрощают или усложняют решение этой проблемы, поэтому в зависимости от вашей ОС и выбранного языка может быть что-то лучше, чем просто примитивы ОС. Win32 (насколько я помню) не делает это очень простым, несмотря на наличие всевозможных примитивов синхронизации. Pthreads и Boost никогда не казались мне очень простыми. GCD от Apple значительно упрощает семантическое выражение того, что вы хотите (по моему мнению), хотя все еще есть подводные камни, о которых следует помнить (например, планирование слишком большого количества блокирующих операций в одной рабочей очереди, чтобы их можно было выполнить). выполняется параллельно и вызывает перегрузку процессора, когда все они просыпаются одновременно).

Мой совет — просто погрузиться и написать много многопоточного кода. Это может быть сложно отлаживать, но вы многому научитесь, и в конечном итоге это станет вашей второй натурой.

person i_am_jorf    schedule 07.08.2013
comment
Я думаю, это вопрос сведения к минимуму шансов на то, что это произойдет, вместо того, чтобы ждать, пока это произойдет. Это действительно сводится к хорошей привычке программирования. Мне просто любопытно, что происходит с процессом, когда происходит перетягивание ресурсов между потоками? - person ccnaflic; 08.08.2013
comment
Когда два потока пытаются получить одну и ту же блокировку, один поток в конечном итоге блокируется. Ваша цель действительно должна состоять в том, чтобы написать код правильно, чтобы не возникало конфликтов ресурсов. Поначалу это может показаться разумным, так как конфликты случаются редко и быстро разрешаются, но со временем программное обеспечение становится только больше и сложнее, и вы обнаружите, что ненадежная основа очень затрудняет его исправление позже. - person i_am_jorf; 08.08.2013