gpt4 book ai didi

linux - 在 Go 中设置进程名称(如 `ps` 所示)

转载 作者:行者123 更新时间:2023-12-01 22:22:32 28 4
gpt4 key购买 nike

以下(正确)不起作用:

package main

import (
"os"
"time"
)

func main() {
os.Args[0] = "custom name"
println("sleeping")
time.Sleep(1000 * time.Second)
println("done")
}

某些语言提供 setting process name 的此功能作为内置功能(例如,在 Ruby 中,这只是 assigning to $0 的问题)或作为第三方库( Python )。

我正在寻找一种至少在 Linux 上有效的解决方案。

最佳答案

有多种方法可以实现这一点,其中许多仅在某些情况下有效。我真的不建议这样做,因为(一方面)它可能会导致您的流程在不同情况下出现不同的名称。它们需要使用系统调用和/或不安全,因此您故意破坏 Go 语言的安全性。尽管如此,您的选择似乎是:

修改 argv[0]

func SetProcessName(name string) error {
argv0str := (*reflect.StringHeader)(unsafe.Pointer(&os.Args[0]))
argv0 := (*[1 << 30]byte)(unsafe.Pointer(argv0str.Data))[:argv0str.Len]

n := copy(argv0, name)
if n < len(argv0) {
argv0[n] = 0
}

return nil
}

在 Go 中,您无法访问实际的 argv 数组本身(无需调用内部运行时函数),因此您只能使用不超过当前进程名称长度的新名称。

这似乎主要适用于 Darwin 和 Linux。

调用 PR_SET_NAME
func SetProcessName(name string) error {
bytes := append([]byte(name), 0)
ptr := unsafe.Pointer(&bytes[0])
if _, _, errno := syscall.RawSyscall6(syscall.SYS_PRCTL, syscall.PR_SET_NAME, uintptr(ptr), 0, 0, 0, 0); errno != 0 {
return syscall.Errno(errno)
}
return nil
}

新名称最多为 16 个字节。

这在 Darwin 上不起作用,并且在 Linux 上似乎没有多大作用,尽管它成功并且 PR_GET_NAME 之后报告了正确的名称。不过,这可能是我的 Linux VM 的一些特殊之处。

关于linux - 在 Go 中设置进程名称(如 `ps` 所示),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62271059/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com