Multithreading Goroutines(cgo):使用Goroutines时,无法解释的操作系统线程生成

Multithreading Goroutines(cgo):使用Goroutines时,无法解释的操作系统线程生成,multithreading,go,cgo,Multithreading,Go,Cgo,我使用go来并行二维卷积,其中卷积(在go中实现)发生在c二进制文件(其中调用go代码)中的c-archive中。go代码不调用任何c函数 在生成goroutine之前,所有矩阵都由c代码加载到内存中,所有goroutine都通过共享内存访问它 我使用GOMAXPROCS-1来决定要生成多少go例程,并且每个例程都被分配了一个ID。goroutine以条带化的方式根据它们的ID被分配到矩阵的行中。go例程在生成时锁定到OS线程,并在完成后释放线程 e、 g。 如果GOMAXPROCS设置为4,则

我使用go来并行二维卷积,其中卷积(在go中实现)发生在c二进制文件(其中调用go代码)中的c-archive中。go代码不调用任何c函数

在生成goroutine之前,所有矩阵都由c代码加载到内存中,所有goroutine都通过共享内存访问它

我使用GOMAXPROCS-1来决定要生成多少go例程,并且每个例程都被分配了一个ID。goroutine以条带化的方式根据它们的ID被分配到矩阵的行中。go例程在生成时锁定到OS线程,并在完成后释放线程

e、 g。 如果GOMAXPROCS设置为4,则goroutine 0将获取第0、4、8、12行等,goroutine 1将获取第1、5、9、13行等

我的问题是,当GOMAXPROCS设置为4时,go会生成11个操作系统线程

htop和顶部:

我的理解是,这些OS线程的产生是因为调度程序试图确保始终存在未被阻止的可用线程

goroutine生成后没有发生I/O或系统调用,因此我不明白调度器为什么要创建所有这些进程,或者是什么阻塞了线程

在具有40个内核的计算机上使用GOMAXPROCS>=20执行时,生成的线程数量正在减慢执行速度

为什么调度程序生成所有这些线程? 如何调试阻止例程的位置/方式


如果没有示例,很难说您应该期望多少,但是所有的C调用都是阻塞的,并且在不同的堆栈上,因此它们必须发生在不同的线程中。添加了到源代码的链接。你的意思是对C.float和C.uchar的调用也被阻塞了,还是对我自己的C函数的调用?我没有从go codeNo调用任何自定义C函数,
C.float
C.uchar
是类型,不是可调用的函数。您说过卷积发生在包含在c二进制文件中的
c-archive中。
,所以我假设您使用cgo调用卷积,尽管您的示例没有cgo调用是正确的。首先,我将删除
LockOSThread
调用(您不能在Go中使用线程本地存储,因此没有理由调用它),然后检查您可能正在进行cgo调用的任何其他位置。感谢您的反馈。我更新了描述,以明确go代码中没有调用c函数。通过删除LockOSThread,创建的线程更少(7个而不是11个),但执行速度会慢几秒钟(从没有锁定的190秒到有锁定的180秒)。将尽可能使用C.float/C.uchar减少铸造。