4.均衡负载,充分利用多核 CPU
taskset -p <PID>该命令会显示进程 ID 为 <PID> 的进程当前的 CPU 亲和性掩码 (affinity mask)。
taskset -p <MASK> <PID>该命令将进程 ID 为 <PID> 的进程的 CPU 亲和性设置为 <MASK> 指定的 CPU 掩码。CPU 掩码是一个十六进制数, 用于表示要被绑定的 CPU 核心。例如, 在一个 4 核心的系统中, 0x1 表示只绑定到第一个 CPU 核心, 0x5 表示绑定到第 1 个和第 3 个 CPU 核心。哪一个位上为 1,就会绑定到哪个核上。
taskset <MASK> <COMMAND> [ARGUMENTS...]该命令会使用 <MASK> 指定的 CPU 亲和性启动一个新进程, 运行命令 <COMMAND> 及其参数 [ARGUMENTS...]。
-a: 获取或设置进程及其所有线程的 CPU 亲和性
默认行为是运行一条新命令: taskset 03 sshd -b 1024 您可以获取现有任务的掩码: taskset -p 700 或设置掩码: taskset -p 03 700 使用逗号分隔的列表格式而不是掩码: taskset -pc 0,3,7-11 700 列表格式中的范围可以带一个跨度参数: 例如 0-31:2 与掩码 0x55555555 等效子进程的 CPU 亲和性
package main import ( "fmt" "os" "os/exec" ) func main() { pid := os.Getpid() // 获取当前进程的 CPU 亲和性 cmd := exec.Command("taskset", "-p", fmt.Sprintf("%d", pid)) out, err := cmd.Output() if err != nil { fmt.Println(err) } // 堆代码 duidaima.com // 设置当前进程的 CPU 亲和性为 CPU 0 和 CPU 1 cmd = exec.Command("taskset", "-p", "0,1", fmt.Sprintf("%d", pid)) out, err = cmd.Output() if err != nil { fmt.Println(err) } fmt.Printf("%s", out) }实际上,你也可以调用系统调用sched_setaffinity来绑核,使用sched_getaffinity来查询 CPU 的亲和性:
package main import ( "fmt" "syscall" "time" "unsafe" ) func main() { var mask uintptr // 获取当前进程的 CPU 亲和性 if _, _, err := syscall.RawSyscall(syscall.SYS_SCHED_GETAFFINITY, 0, uintptr(unsafe.Sizeof(mask)), uintptr(unsafe.Pointer(&mask))); err != 0 { fmt.Println("failed to get CPU affinity:", err) return } fmt.Println("current CPU affinity:", mask) // 堆代码 duidaima.com // 设置当前进程的 CPU 亲和性为 CPU 0 和 CPU 1 mask = 3 if _, _, err := syscall.RawSyscall(syscall.SYS_SCHED_SETAFFINITY, 0, uintptr(unsafe.Sizeof(mask)), uintptr(unsafe.Pointer(&mask))); err != 0 { fmt.Println("failed to set CPU affinity:", err) return } fmt.Println("new CPU affinity:", mask) for { println("Hello, World!") time.Sleep(1 * time.Second) }}