当前位置: 首页 > 面试题库 >

C回调和非Go线程

郜琦
2023-03-14
问题内容
  1. 如何用非Go创建的线程在C中调用Go代码?
  2. 我应为C函数指针分配什么,以便非Go创建的线程可以调用该指针并输入Go代码?

更新0

  • 我不想使用SWIG。
  • 回调将来自Go从未见过的线程。AFAICT 均未显示cgo/life任何pkg/runtime行为。

问题答案:

我假设您的意思是使用gcc编译的C代码?

IIRC,使用6g + cgo和朋友无法完成或无法轻松完成。Go使用不同的调用约定(以及分段堆栈等)。

但是,您 可以 为[685] c(甚至[685]
a)编写C代码,并使用package·function()轻松调用go(甚至可以调用IIRC方法)。有关示例,请参见软件包的来源runtime

更新:

更新后再回到这个问题,并再考虑一下。使用6c或cgo无法以标准方式完成此操作。特别是因为线程不是由go运行时启动的,所以当前的实现会失败。调度程序突然将一个它不知道的线程置于其控制之下。另外,该线程将缺少go运行时用于管理堆栈的其他线程局部变量和其他一些东西。另外,如果go函数返回一个(或多个)值,那么C代码将无法在当前支持的平台上访问它,因为go返回了堆栈中的值(不过您可以使用汇编程序来访问它们)。考虑到这些事情,我相信您仍然可以使用渠道进行此操作。这将需要您的C代码与go运行时的内部工作过于亲密,但对于给定的实现它会起作用。虽然使用通道可能不是您要寻找的解决方案,但它可能比回调更适合Go的概念。如果您的C代码至少重新实现了发送方法,通道实现(该代码是为6c编写的,因此很可能必须针对gcc进行修改,并且它调用go运行时,我们已经确定无法通过非执行线程完成该运行时),您应该能够锁定通道并向其推送值。go调度程序可以继续管理自己的线程,但是现在它可以从C中启动的其他线程接收数据。

诚然,这是黑客。我的距离还不够近,但是可能还需要一些其他技巧才能使其正常工作(我相信渠道本身会维护正在等待它们的goroutine的列表[EDIT:Confirmed:runtime·ready(gp);],因此您需要您的Go代码中的某些内容会唤醒接收通道或保证Go代码不会在您已推入值之前在该通道上接收)。不过,我看不出任何原因,这
不能 工作,而有一些产生以6克代码运行在C不能创建一个线程明确的原因。

我的原始答案仍然成立: 除非在语言或运行时中添加任何内容,否则尚无法 按照您希望的方式进行(我很乐意在此证明是错误的)。



 类似资料:
  • 只要不使用C的标准库函数,Go中是可以直接调用C和汇编语言的。其实道理很简单,Go的运行时库就是用C和汇编实现的,Go必须是能够调用到它们的。当然,会有一些额外的约束,这就是函数调用协议。 Go中调用汇编 假设我们做一个汇编版本的加法函数。首先GOPATH的src下新建一个add目录,然后在该目录加入add.go的文件,内容如下: package add func Add(a, b uint64

  • cgo不仅仅支持从Go调用C,它还同样支持从C中调用Go的函数,虽然这种情况相对前者较少使用。 //export GoF func GoF(arg1, arg2 int, arg3 string) int64 { } 使用export标记可以将Go函数导出提供给C调用: extern int64 GoF(int arg1, int arg2, GoString arg3); 下面让我们看看它是

  • 从这里开始,将深入挖掘关于运行时库部分对于cgo的支持。还记得前面那个test.go吗?这里将继续以它为例子进行分析。 从Go中调用C的函数test,cgo生成的代码调用是runtime.cgocall(_cgo_Cfunc_test, frame): void ·_Cfunc_test(struct{uint8 x[8];}p) { runtime·cgocall(_cgo_1b9ecf7f7

  • Go支持函数回调,你可以把函数名称作为参数传递给另外一个函数,然后在别的地方实现这个函数。 package main import "fmt" type Callback func(x, y int) int func main() { x, y := 1, 2 fmt.Println(test(x, y, add)) } //提供一个接口,让外部去实现 func test(x,

  • 问题内容: 我正在尝试创建一个用Go语言编写的静态对象,以与C程序(例如内核模块等)进行接口。 我已经找到了有关从Go调用C函数的文档,但是关于如何走另一条路却找不到很多。我发现这是可能的,但很复杂。 这是我发现的: 有关C和Go之间的回调的博客文章 CGO文档 Golang邮件列表帖子 有任何人对此有经验吗?简而言之,我正在尝试创建一个完全用Go编写的PAM模块。 问题答案: 您可以从C调用Go

  • 问题内容: syscall 返回-1,而set 是一个简单的情况。我对C 调用返回零或正的状态感兴趣。该包装在围棋简单的返回,如果不是任何情况下,其中还包括的零的情况下调用返回正数。 https://github.com/golang/go/blob/3cb64ea39e0d71fe2af554cbf4e99d14bc08d41b/src/syscall/zsyscall_linux_386.go