完整代码如下:
//#define _GNU_SOURCE
#include <sys/wait.h> // 包含 wait 函数
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
typedef void (*spawn_proc_pt) (void *data);
static void worker_process_cycle(void *data);
static void start_worker_processes(int n);
pid_t spawn_process(spawn_proc_pt proc, void *data, char *name);
int main(int argc,char **argv){
//产生4个子进程
start_worker_processes(4);
//管理子进程
wait(NULL);
}
void start_worker_processes(int n){
int i=0;
for(i = n - 1; i >= 0; i--){
spawn_process(worker_process_cycle,(void *)(intptr_t) i, "worker process");
}
}
//返回类型是pid_t
pid_t spawn_process(spawn_proc_pt proc, void *data, char *name){
pid_t pid;
//创建进程
pid = fork();
switch(pid){
case -1:
fprintf(stderr,"fork() failed while spawning \"%s\"\n",name);
return -1;
case 0:
//进行工作,绑定内核,通过proc()函数指针指向的函数去完成.
proc(data);
return 0;
default:
break;
}
printf("start %s %ld\n",name,(long int)pid);
return pid;
}
static void worker_process_init(int worker){
cpu_set_t cpu_affinity;
//worker = 2;
//多核高并发处理 4core 0 - 0 core 1 - 1 2 -2 3 -3
CPU_ZERO(&cpu_affinity);
CPU_SET(worker % CPU_SETSIZE,&cpu_affinity);// 0 1 2 3
//sched_setaffinity
if(sched_setaffinity(0,sizeof(cpu_set_t),&cpu_affinity) == -1){
fprintf(stderr,"sched_setaffinity() failed\n");
}
}
void worker_process_cycle(void *data){
int worker = (intptr_t) data;
//初始化
worker_process_init(worker);
//干活
for(;;){
sleep(5);
printf("pid %ld ,working ...\n",(long int)getpid());
}
}
函数调用关系如下图:
各个函数的功能:
main函数,调用start_worker_processes(4)产生子进程后进入等待状态
int main(int argc,char **argv){
//产生4个子进程
start_worker_processes(4);
//管理子进程
wait(NULL);
}
start_worker_processes函数,根据传入参数n,循环n次
n次调用 spawn_process产生n个子进程
void start_worker_processes(int n){
int i=0;
for(i = n - 1; i >= 0; i--){
spawn_process(worker_process_cycle,(void *)(intptr_t) i, "worker process");
}
}
spawn_process,真正创建进程通过该函数里的pid = fork()创建
并通过switch判断返回值,判断进程是否被成功创建
如果创建成功,通过函数指针proc调用worker_process_cycle函数
pid_t spawn_process(spawn_proc_pt proc, void *data, char *name){
pid_t pid;
//创建进程
pid = fork();
switch(pid){
case -1:
fprintf(stderr,"fork() failed while spawning \"%s\"\n",name);
return -1;
case 0:
//进行工作,绑定内核,通过proc()函数指针指向的函数去完成.
proc(data);
return 0;
default:
break;
}
printf("start %s %ld\n",name,(long int)pid);
return pid;
}
worker_process_init函数,进程绑定内核在此处实现
static void worker_process_init(int worker){
cpu_set_t cpu_affinity;
//worker = 2;
//多核高并发处理 4core 0 - 0 core 1 - 1 2 -2 3 -3
CPU_ZERO(&cpu_affinity);
CPU_SET(worker % CPU_SETSIZE,&cpu_affinity);// 0 1 2 3
//sched_setaffinity
if(sched_setaffinity(0,sizeof(cpu_set_t),&cpu_affinity) == -1){
fprintf(stderr,"sched_setaffinity() failed\n");
}
}
worker_process_cycle函数,调用 worker_process_init绑定进程
之后每五秒打印一次自己的进程号pid
void worker_process_cycle(void *data){
int worker = (intptr_t) data;
//初始化
worker_process_init(worker);
//干活
for(;;){
sleep(5);
printf("pid %ld ,working ...\n",(long int)getpid());
}
}
接下在ubuntu上来编译运行该程序
我的虚拟机是设置的4个内核,可通过这个命令查看内核情况:cat /proc/cpuinfo
所以我代码中绑定四个进程到四个内核上,数量刚刚好。
编译后,整段代码的运行结果如下:
输入命令:ps -eLo ruser,pid,lwp,psr,args
查看进程在cpu的核上执行情况,如下图:
往下翻 ,可见7074,7075,7076,7077这四个进程,分别在3,2,1,0,这四个核心上运行,如下图
另外,7073是主进程,7074,7075,7076,7077是主进程产生的子进程