Nginx采用多进程Master/Worker结构,Worker进程数为CPU个数时工作效率最高,Nginx通过affinity为每个Worker进程绑定一个CPU,避免进程切换带来的消耗,同时能够保证缓存命中率。

Nginx配置文件conf/nginx.conf中关于Worker进程个数,和affinity的配置命令:

worker_processes  4;
worker_cpu_affinity 1000 0100 0010 0001;

应用程序可以主动调用接口设定:

Linux进程:

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

例子:

 1 #define _GNU_SOURCE
 2 
 3 #include <sched.h>
 4 #include <unistd.h>
 5 
 6 void do_something(void);
 7 
 8 int 
 9 main(void)
10 {
11     pid_t pid;
12     cpu_set_t mask;
13 
14     if((pid = fork()) == 0){
15         do_something();
16     }
17     CPU_ZERO(&mask);
18     CPU_SET(0,&mask);
19     sched_setaffinity(pid,sizeof(cpu_set_t),&mask);
20 
21     if((pid = fork()) == 0){
22         do_something();
23     }
24     CPU_ZERO(&mask);
25     CPU_SET(1,&mask);
26     sched_setaffinity(pid,sizeof(cpu_set_t),&mask);
27 
28     wait();
29     wait();
30 }    
31 
32 void
33 do_something(void)
34 {
35     int i;
36     while(1){
37         i = 1;
38     }        
39 }
sched_setaffinity

FreeBSD上可以通过调用cpuset_setaffinity设定

Nginx源码src/os/unix/nginx_setaffinity.c中实现对Linux和FreeBSD中设置亲和性的包装,根据配置文件设置Worker进程亲和性

当然,POSIX线程也可以设置亲和性:

int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize,
                                  const cpu_set_t *cpuset);
int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize,
                                  cpu_set_t *cpuset);

 

已经运行的进程也可以通过外部命令设定:

       taskset [options] mask command [arg]...
       taskset [options] -p [mask] pid

 

 posted on 2015-07-28 10:01  莫扎特的代码  阅读(1438)  评论(0编辑  收藏  举报