X86下进程克隆及与CPU线程绑定介绍

本文深入探讨了Linux中的进程调度机制,通过使用`sched_setaffinity`和`sched_getaffinity`函数来实现进程与特定CPU核心的绑定,展示了如何利用这些API在多核系统中优化进程性能。同时,介绍了`clone`函数的使用及其各种标志参数,以创建具有不同资源继承特性的子进程。并通过示例代码展示了如何创建多个子进程并分别绑定到不同的物理核心,以及内存分配和进程间共享状态的基本原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1头文件

#include <sched.h>

#include<pthread.h>

2函数原型

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

int sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask);

void CPU_CLR(int cpu, cpu_set_t *set);

int CPU_ISSET(int cpu, cpu_set_t *set);

void CPU_SET(int cpu, cpu_set_t *set);

void CPU_ZERO(cpu_set_t *set);

clone函数

#include <sched.h>

int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...);

clone() 类似于fork()函数创建一个新的进程。

这里fn是函数指针,指向子进程的应用函数指针, child_stack为子进程分配堆栈空间(在linux下系统堆栈空间是2页面,就是8K的内存,其中在这块内存中,低地址上放入了值,这个值就是进程控制块task_struct的值, flags就是标志用来描述你需要从父进程继承那些资源, arg就是传给子进程的参数)

flags可取值:

标志                   含义

CLONE_PARENT         创建的子进程的父进程是调用者的父进程,新进程与创建它的进程成了兄弟而不是父子

CLONE_FS                 子进程与父进程共享相同的文件系统,包括root、当前目录、umask

CLONE_FILES            子进程与父进程共享相同的文件描述符(file descriptor)表

CLONE_NEWNS         在新的namespace启动子进程,namespace描述了进程的文件hierarchy

CLONE_SIGHAND        子进程与父进程共享相同的信号处理(signal handler)表

CLONE_PTRACE         若父进程被trace,子进程也被trace

CLONE_VFORK           父进程被挂起,直至子进程释放虚拟内存资源

CLONE_VM                 子进程与父进程运行于相同的内存空间

CLONE_PID                子进程在创建时PID与父进程一致

CLONE_THREAD          Linux 2.4中增加以支持POSIX线程标准,子进程与父进程共享相同的线程群

通过不同的flag参数的传递,是的子进程和父进程共享不同的空间。这样就看起来是的子线程看起来像一个子进程。

在应用中可以采用:

#define CLONE_BUDDY_FLGS (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD )

示例代码运行结果

       [root@localhost codeset]# gcc -o psbind psbind.c -lpthread

[root@localhost codeset]# ./psbind

Process (5200) is created and bound to CPU (0)

Process (5201) is created and bound to CPU (1)

Process (5201) is created and bound to CPU (1)

allocate memory in cpu(1)

cpu (1) value before change is: 5201

cpu (1) value after change is: 1

cpu (0) value before change is: 1

cpu (0) value after change is: 0

5运行结果分析

       首先,在void process_bind_x86()函数中采用clone函数创建了新的子进程,并依次绑定了物理线程上。

       然后,各个子进程开始运行,执行函数int process_packet(void *args)。在该函数中,判断全局变量是否有开辟内存,如果没有则开内存,并赋初值为当前进程号,然后打印初值和改变值(改成当前物理线程号)如果已经开辟,直接打印全局变量的值,并将其修改成进程所在的物理线程号。物理线程号的获取通过获取亲属性判断。

总结:通过本实例,可以看到,通过clone创建的子进程绑定了实际的物理线程,并且在任何线程开辟的内存,其他线程都是可以读写的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值