MacOS下proc_listpids函数返回值如何正确解读?
关于macOS中proc_listpids返回值的疑问
我在macOS上尝试获取PID列表,libproc.h中包含proc_listpids的函数签名,但找不到相关文档:
int proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
我用Swift编写了如下示例代码:
let arr = UnsafeMutableRawPointer.allocate(byteCount: 5000 * MemoryLayout<Int32>.stride, alignment: MemoryLayout<Int32>.alignment) let count = proc_listpids(UInt32(PROC_ALL_PIDS), 0, arr, Int32(5000 * MemoryLayout<Int32>.stride)); print("count \(count)") let pointer = arr.assumingMemoryBound(to: Int32.self) let pids = Array(UnsafeMutableBufferPointer(start:pointer, count:Int(count))) let slice = pids[0..<Int(count)] for i in 0..<Int(count) { print("index:\(i) pid:\(slice[i])") }
原本以为返回的count是找到的PID数量,但输出显示后续元素多为0:
count 2020 index:0 pid:7727 index:1 pid:7726 index:2 pid:7723 index:3 pid:7722 index:4 pid:7721 index:5 pid:7717 ... index:502 pid:94 index:503 pid:1 index:504 pid:0 index:505 pid:0 index:506 pid:0 ... index:2013 pid:0 index:2014 pid:0 index:2015 pid:0 index:2016 pid:0 index:2017 pid:0 index:2018 pid:0 index:2019 pid:0
因此我对proc_listpids函数实际返回值的含义感到困惑,该如何解读?
问题解析与结论
proc_listpids的返回值是写入缓冲区的字节总数,而非实际PID的数量。- 每个PID以
int32_t类型存储(占4字节),因此实际有效的PID数量需要用返回的字节数除以MemoryLayout<Int32>.stride(即4)来计算。
修正后的Swift代码
let pidStride = MemoryLayout<Int32>.stride let bufferByteSize = 5000 * pidStride let buffer = UnsafeMutableRawPointer.allocate(byteCount: bufferByteSize, alignment: pidStride) defer { buffer.deallocate() } // 确保内存被释放,避免泄漏 let bytesWritten = proc_listpids(UInt32(PROC_ALL_PIDS), 0, buffer, Int32(bufferByteSize)) let actualPidCount = bytesWritten / pidStride print("实际PID数量: \(actualPidCount)") let pidPointer = buffer.assumingMemoryBound(to: Int32.self) let pidBuffer = UnsafeMutableBufferPointer(start: pidPointer, count: actualPidCount) let pids = Array(pidBuffer) for (index, pid) in pids.enumerated() { print("index:\(index) pid:\(pid)") }
补充说明
- 原代码中直接将返回的字节数当作数组长度,导致后面的元素是缓冲区未被写入的初始0值——函数仅会将有效PID数据写入对应字节长度的空间,剩余缓冲区不会被修改。
- 必须手动释放通过
allocate分配的内存,使用defer语句可以确保代码执行完毕后自动回收资源。
内容的提问来源于stack exchange,提问作者egor10_4
相关产品推荐
相关产品推荐

