Jim*_*mbo 4 windows go goroutine
如何在Windows上将goroutine的运行委托给另一个非管理员帐户?我看到你可以在Linux上使用syscall.Setuid()
.我无法使用Windows系统调用包在Windows上看到如何执行此操作.我希望能够在程序运行时设置goroutine运行的帐户.这可能吗?
一点背景: -我想切换运行goroutine的用户,这样我就可以在使用go-oci8时更改在数据库连接期间传递给Oracle的OS用户(参见我的其他问题).我需要连接到数据库,它使用登录用户(OS用户)作为安全性的一部分.在java中,我可以在连接设置期间更改环境变量(如果仅为单个用户连接,则轻弹用户名环境变量).
我有用户数据库用户名(这与操作系统用户名匹配),我获得了数据库用户密码.我没有用户的Windows登录密码.我希望能够以运行管理员的主要go程序将运行goroutine委托给所需的Windows用户,其方式类似于我强调的Linux端口绑定示例.将Oracle登录更改为不使用操作系统用户不是一个选项,因此如果我无法解决它将返回Java :-(.
理论上,不,这是不可能的,因为在Linux和Windows上,用户身份的概念仅存在于OS级线程,而goroutine 不是 OS线程 - 相反,它们是非常轻量级的实体,映射到真实OS线程通过Go调度程序(内置于可执行文件中的Go运行时的一部分),并且在其生命周期中,可以在不同的时间在不同的OS线程上执行goroutine.
但是,对于您最初设计用于帮助调用C
代码的情况,存在一种"退出舱口" :runtime.LockOSThread()
.一旦goroutine调用此函数,它就会停留在当前正在运行的线程上,并且无论是什么直到goroutine退出或调用都不会被安排在另一个上调用runtime.UnlockOSThread()
.
您可以像这样使用:
go func() {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
impersonate() // acquires and assumes some other credentials
...
}
Run Code Online (Sandbox Code Playgroud)
该假想impersonate()
函数的实现超出了本问题的范围; 您可以使用该syscall
包调用任何Win32 API函数- 请参阅标准Go库以获取示例.
请注意,调用runtime.LockOSThread()
真实世界的结果是将整个操作系统线程专用于单个goroutine(虽然通常很多只运行在一个goroutine上)所以如果你计划产生很多这样的goroutine锁定到OS线程准备好应对增加的OS资源使用.
更新: 使用Go 1.2.1/i386在Windows XP Pro SP3 32位上测试的工作示例.
它硬编码由密码"foo"标识的用户"foo".要在Windows上快速创建用户,请执行
net user foo * /ADD
Run Code Online (Sandbox Code Playgroud)
并在提示时键入两次密码.