#define _GNU_SOURCE
#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);
主函数中,启动4个子进程后,对子进程进行管理
int main(int argc,char **argv){
start_worker_processes(4); //启动了4个子进程
//管理子进程
wait(NULL);
}
在start_worker_processes()函数中,用for循环分别调用了4次spawn_process()函数
spawn_process()中的前两个参数分别为函数指针,函数指针所指向函数的所带参数。
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()中,根据fork()的返回值确定进程是子进程还是父进程,若返回0,则说明产生子进程,并执行子进程任务,pro为传入的函数名,data为传入函数所需的参数;若返回正数,则为父进程;若返回负数,则说明创建进程失败。
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(data); //若是0,则说明产生子进程,开始执行子进程的任务
return 0;
default: //若是父进程,则直接break,并打印启动了哪些子进程
break;
}
printf("start %s %ld\n",name,(long int)pid);
return pid;
}
该函数在创建子进程后,被调用,在该函数中,调用worker_process_init(),建立CPU的亲缘关系,并指定后续该进程要完成的任务。
void worker_process_cycle(void *data){
int worker = (intptr_t) data;
//初始化
worker_process_init(worker);
//干活
for(;;){
sleep(10);
printf("pid %ld ,doing ...\n",(long int)getpid());
}
}
worker_process_init(),建立CPU的亲缘关系。将进程绑定到指定的CPU上。
static void worker_process_init(int worker){ //绑定CPU的亲缘关系,将进程绑定在CPU的某个核上
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
//%CPU_SETSIZE取模最大CPU数量
//sched_setaffinity
if(sched_setaffinity(0,sizeof(cpu_set_t),&cpu_affinity) == -1){
fprintf(stderr,"sched_setaffinity() failed\n");
}
}