Насколько я знаю, планировщик времени выполнения Go управляет некоторым количеством потоков ОС (вероятно, больше, чем GOMAXPROCS?) и подпрограммами Go, постоянно назначая подпрограммы Go потокам ОС.
Таким образом, это в основном означает, что выполнение подпрограмм Go, включая основную горутину, управляется как планировщиком go, так и планированием потоков ОС.
Теперь вот мои вопросы..
Будет ли выполнение горутины полностью управляться планированием потоков ОС, если я вызову
runtime.LockOSThread()
в начале этой горутины?Полностью ли выполнение потока, отличного от Go, также полностью управляется планированием потоков ОС? Другими словами, если я создаю поток, отличный от Go, с помощью функции
CreateThread
(Windows), то управление выполнением потока, отличного от Go, выходит за рамки планировщика времени выполнения Go?Что, если я запущу еще одну горутину с
go func()
в этом потоке, отличном от Go? Как управляется выполнение этого потока, не относящегося к Go, и горутины?В настоящее время я пишу программу на Golang, которая запускает цикл сообщений Windows в функции
main()
программы go. Большую часть времени это работало хорошо, но иногда цикл сообщений блокировался и возобновлялся через несколько секунд, а затем загружалось большое количество старых сообщений. (Еще один мой вопрос: Цикл сообщений Windows блокируется и возобновляется с перерывами (голанг))Я понятия не имел, почему это происходит, поэтому я подозревал, что основная горутина переключает поток ОС с помощью планировщика go. Поэтому я добавил
runtime.LockOSThread()
в начале функцииmain()
, чтобы цикл сообщений Windows всегда выполнялся в одном и том же потоке. Однако проблема все же возникла!Я до сих пор не знаю, почему это происходит, но я подозреваю, что это из-за планировщика Go, потому что та же логика, написанная на Python 3.4, не создавала таких проблем.
Итак, сейчас я пытаюсь создать новый поток Windows (не-Go Thread), вызвав функцию
CreateThread(...)
и запустив цикл сообщений Windows в этом потоке.Но мне любопытно, отличается ли этот подход от вызова
runtime.LockOSThread()
в основной горутине, выполняющей цикл сообщений Windows, с точки зрения планировщика времени выполнения Go.Итак, мой вопрос: «Если я создаю новый поток, отличный от Go, с функцией
CreateThread(...)
и запускаю цикл сообщений Windows в этом потоке, не влияет ли планировщик времени выполнения Go на выполнение этого потока?»
Любая помощь или идеи будут с благодарностью. Спасибо.
runtime
и посмотрите, можете ли вы использовать одну из настроек переменной средыGODEBUG
, чтобы увидеть, соответствуют ли получаемые вами паузы паузам сборщика мусора или нет. В качестве альтернативы вы можете попробовать это: используйтеCreateThread()
из некоторого кода C, чтобы создать поток, о котором Go не знает, и создайте там свое окно и перекачивайте сообщения. Управление памятью здесь будет немного сложнее, ноSendMessageW()
можно использовать для отправки сообщений между потоками, поэтому базовая связь от Go к C будет работать. (Я собирался сделать это с моим пакетным интерфейсом перед тем, как начать переписывать libui. Я все еще мог бы это сделать.) - person andlabs   schedule 16.02.2017runtime.LockOSThread()
вам не помогло, вы публикуете новый вопрос с общими и неясными вопросами, а затем продолжаете обсуждение проблемы вашего предыдущего вопроса? Для этого и предыдущий пост! Что касается вашего вопроса об используемых инструментах: (1) прикрепите отладчик после блокировки; (2) Создайте дамп после блокировки; (3) Используйте Process Explorer/Process Hacker, чтобы увидеть, что делают потоки, когда вы заблокированы; (4) Запустите вашу программу под профилировщиком; (5) ... - person conio   schedule 17.02.2017