1

我需要为 Linuxsched_setaffinity函数提供 P/Invoke 签名,以便从在 Mono 上运行的 C# 代码调用。

int sched_setaffinity(pid_t pid, size_t cpusetsize,
                      cpu_set_t *mask);

ThreadAffinity“open-hardware-monitor”项目中的类将其定义为:

[DllImport(LIBC)]
public static extern int sched_setaffinity(int pid, IntPtr maskSize,
                                           ref ulong mask);  

但是,Mono.LibRt项目使用不同的签名:

[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl,
                  SetLastError=true, EntryPoint="sched_setaffinity")]
protected static extern int sched_setaffinity (long pid, int num_bytes, 
                                               byte[] affinity);

两个签名都正确,还是一个错误?它们可以跨 32 位和 64 位架构移植吗?

我假设第一个参数应该是int,而不是long,因为pid_t在 32 位和 64 位平台上都是有符号的 32 位整数(根据Joe Shaw)。同样,第二个应该是UIntPtrIntPtr根据Patrick McDonald。但是,我不知道如何处理第三个参数。

编辑:基于 Simon Mourier 的评论:我从cpu_set_t *类型中收集到第三个参数应该是一个指针。有ref ulong资格吗?我很想使用这种类型,因为它使宏更容易实现;例如,单个处理器的掩码id可以计算为:

ulong mask = 1UL << id;

cpu_set_t在 this中找到了一个定义sched.h,它被实现为unsigned long int.

4

2 回答 2

1

正如您所发现的,cpu_set_t 只是一个 unsigned long int 数组。所以我会这样声明函数:

[DllImport("libc.so.6", SetLastError=true)]
private static extern int sched_setaffinity(
    int pid, 
    IntPtr cpusetsize, 
    ulong[] cpuset
);
于 2014-01-18T16:38:15.723 回答
0

根据我的另一个答案,我选择了前一个选项(在 Linux 上运行良好)。

[DllImport("libc.so.6", SetLastError=true)]
private static extern int sched_setaffinity(int pid, IntPtr cpusetsize, 
                                            ref ulong cpuset);
于 2014-01-18T16:10:46.800 回答