Reputation: 11
How to set priority of a process(that gets inherited by OS threads) in golang for mac? syscall.SetPriority with syscall.PRGRP flag sets priority of a process and gets inherited by threads on ubuntu. Is there a similar way for mac? How can we access apple qos from golang?
Program worked on ubuntu but didn't work on mac
package main
import (
"fmt"
"os"
"runtime"
"sync"
"syscall"
"time"
)
func main() {
// runtime.GOMAXPROCS(5)
// Get the current process ID
pid := os.Getpid()
fmt.Printf("Current Process ID: %d\n", pid)
// Set process priority to the lowest
setProcessPriority(pid, syscall.PRIO_PGRP, 10)
// Number of goroutines to spawn
numGoroutines := 100
// Use a wait group to wait for all goroutines to finish
var wg sync.WaitGroup
wg.Add(numGoroutines)
start := time.Now()
// Spawn goroutines
for i := 0; i < numGoroutines; i++ {
go func(id int) {
defer wg.Done()
fmt.Printf("Goroutine %d started.\n", id)
cpuIntensiveWork()
fmt.Printf("Goroutine %d completed.\n", id)
}(i)
}
// Wait for all goroutines to finish
wg.Wait()
elapsed := time.Since(start)
fmt.Printf("All goroutines completed in %f\n.", elapsed.Seconds())
}
func setProcessPriority(pid int, which int, priority int) {
if runtime.GOOS == "windows" {
fmt.Println("Setting process priority is not supported on Windows.")
return
}
// Set process priority for Unix-like systems
err := syscall.Setpriority(which, pid, priority)
if err != nil {
fmt.Println("Error setting process priority:", err)
}
}
func cpuIntensiveWork() {
// Simulate CPU-intensive work
for i := 0; i < 100000; i++ {
for j := 0; j < 10000; j++ {
_ = j * j
}
_ = i * i
}
}
Upvotes: 1
Views: 309
Reputation: 7469
Your program fails for me on Linux and macOS. The problem is your use of syscall.PRIO_PGRP
where you should be using syscall.PRIO_PROCESS
. I simplified your program to the following and it works as expected on Linux and macOS.
package main
import (
"fmt"
"os"
"syscall"
)
func main() {
pid := os.Getpid()
fmt.Printf("Current Process ID: %d\n", pid)
prio, err := syscall.Getpriority(syscall.PRIO_PROCESS, pid)
if err != nil {
fmt.Println("Error getting process priority:", err)
}
fmt.Println("Original priority:", prio)
if err := syscall.Setpriority(syscall.PRIO_PROCESS, pid, 10); err != nil {
fmt.Println("Error setting process priority:", err)
}
prio, err = syscall.Getpriority(syscall.PRIO_PROCESS, pid)
if err != nil {
fmt.Println("Error getting process priority:", err)
}
fmt.Println("New priority:", prio)
}
On macOS:
$ go run x.go
Current Process ID: 27436
Original priority: 0
New priority: 10
On Linux:
$ go run x.go
Current Process ID: 117032
Original priority: 20
New priority: 10
If you change the syscall.PRIO_PROCESS
to syscall.PRIO_PGRP
you'll see errors like the following on both platforms:
Current Process ID: 113604
Error getting process priority: no such process
Original priority: -1
Error setting process priority: no such process
Error getting process priority: no such process
New priority: -1
Upvotes: 0