Winapi Go调度程序是否也管理在运行时创建的非Go线程?

Winapi Go调度程序是否也管理在运行时创建的非Go线程?,winapi,go,Winapi,Go,据我所知,Go运行时调度器通过连续地将Go例程分配给OS线程来管理一些OS线程(可能比GOMAXPROCS多?)和Go例程 因此,这基本上意味着Go例程的执行,包括主goroutine,由Go调度程序和操作系统的线程调度管理 下面是我的问题 如果在goroutine开始时调用runtime.LockOSThread(),goroutine的执行是否完全由操作系统的线程调度管理 非Go线程的执行是否也完全由操作系统的线程调度管理?换句话说,如果我通过CreateThread函数(Windows)创

据我所知,Go运行时调度器通过连续地将Go例程分配给OS线程来管理一些OS线程(可能比GOMAXPROCS多?)和Go例程

因此,这基本上意味着Go例程的执行,包括主goroutine,由Go调度程序和操作系统的线程调度管理

下面是我的问题

  • 如果在goroutine开始时调用
    runtime.LockOSThread()
    ,goroutine的执行是否完全由操作系统的线程调度管理

  • 非Go线程的执行是否也完全由操作系统的线程调度管理?换句话说,如果我通过
    CreateThread
    函数(Windows)创建一个非执行线程,那么管理非执行线程的执行超出了Go的运行时调度器的范围

  • 如果我在非go线程中启动另一个goroutine并使用
    go func()
    ,该怎么办?如何管理非Go线程和goroutine的执行

  • 目前,我正在Golang编写一个程序,在go程序的
    main()
    函数中运行windows消息循环。 大多数情况下,它工作得很好,但有时消息循环会被阻塞并在几秒钟后恢复,然后大量的旧消息被释放。 (我的另一个问题是:)

    我不知道为什么会发生这种情况,所以我怀疑主goroutine的OS线程切换是通过go调度程序实现的。因此,我在
    main()
    函数的开头添加了
    runtime.LockOSThread()
    ,以确保windows消息循环始终在同一线程中运行。 但是,问题还是出现了

    我仍然不知道为什么会发生这种情况,但我怀疑这是因为Go scheduler,因为用Python3.4编写的相同逻辑没有出现类似的问题

    所以我现在尝试的是通过调用
    CreateThread(…)
    函数创建一个新的Windows线程(非Go线程),并在该线程中运行Windows消息循环

    但我很好奇,从Go运行时调度器的角度来看,这种方法是否与在运行windows消息循环的主goroutine中调用
    runtime.LockOSThread()
    不同

    所以我的问题是,‘如果我使用
    CreateThread(…)
    函数创建一个新的非Go线程,并在该线程中运行windows消息循环,那么该线程的执行是否不受Go的运行时调度程序的影响?’

  • 任何帮助或想法都将不胜感激。
    谢谢。

    如果使用
    CreateThread()
    例程运行新的操作系统线程,Go的调度程序将不会触及该线程。但是,您必须实现一种方法,使该线程能够与goroutine通信。例如,您不能直接从
    CreateThread()
    创建的线程调用Go方法。相反,您必须使用一些基于C的系统来轮询Goroutine中的事件

    另外,如果要从主操作系统线程运行循环,应该在
    init()
    中调用
    LockOSThread()
    ,而不是在
    main()
    中调用。见:


    我相当肯定,如果没有运行时的支持,您无法安全地使用新的OS线程,无论是让运行时生成线程还是使用cgo。您无法将goroutine绑定到线程,这比使用LockOSThread更好。我想你需要知道你的应用程序被阻止时在做什么。@JimB谢谢你的评论。当我的应用程序被阻止时,我很难弄清楚它在做什么。。因为这个问题是随机发生的。你能给我一些建议或工具来弄清楚我的程序被阻止时在做什么吗?感谢检查包
    运行时
    文档,并查看是否可以使用
    GODEBUG
    环境变量设置之一来查看您获得的暂停是否对应于GC暂停。您也可以尝试这样做:使用一些C代码中的
    CreateThread()
    来创建Go不知道的线程,并在其中创建窗口和泵送消息。内存管理在这里会有点困难,但是可以使用
    sendmaessew()
    跨线程发送消息,因此从Go到C的基本通信将起作用。(在开始重写libui之前,我打算对我的包ui执行此操作。我可能仍然会执行此操作。)与其继续处理上一个问题并回答
    runtime.LockOSThread()
    对您没有帮助,您发布了一个新问题,其中包含一般性和不明确的问题,然后继续讨论上一个问题的问题?这就是上一篇文章的目的!至于你要使用的工具的问题:(1)一旦你被阻止,附加一个调试器;(2) 一旦被阻止,生成转储;(3) 使用Process Explorer/Process Hacker查看被阻止时线程正在执行的操作;(4) 在分析器下运行程序;(5) …谢谢你的回答。在
    init()
    函数中调用
    LockOSThread()
    main()
    函数有什么区别?如果我在
    main()
    函数的开头调用
    LockOSThread()
    ,调用goroutine get locked to os thread不是吗?在init中使用LockOSThread()可以确保main()从主os线程运行。通常,特定于操作系统的API(如runloops)只有在从主线程调用时才能正常工作。我不知道windows runloop的情况是否如此——它可能不是。真的很晚了,但为了谷歌的利益:在它被明确记录为这样做之前,
    runtime.LockOSThread()
    即使在
    init()
    中运行,也不能保证任何东西。当然,Windows不关心你在哪个线程上做特定于线程的事情,只要你选择一个。(OS X是一个要求在OS创建的第一个线程上运行循环的OS示例。)
    func init() {
        runtime.LockOSThread();
    }
    func main() {
        // Run loop here.
    }