为什么nginx多核效率更高,主要进行了多进程绑定cpu,提高程序的效率。减少cpu轮换切换时间。下面代码模拟
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <iostream>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include<sys/syscall.h>
#include<sched.h>
#define MAX_EPOLLSIZE 1024
int init_server(){
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
perror("socket");
return 1;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(6666);
if( bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) == -1){
printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
exit(0);
}
if( listen(sockfd, 10) == -1){
printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
exit(0);
}
return sockfd;
}
int main_loop(int sockfd){
//创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大
int epfd = epoll_create(1);//生成用于处理accept的epoll专用的文件描述符
struct epoll_event ev;
ev.events = EPOLLIN |EPOLLET;
ev.data.fd = sockfd;
epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
struct epoll_event events[MAX_EPOLLSIZE];
while(1){
int nfds = epoll_wait(epfd, events, MAX_EPOLLSIZE, 5);
int i =0 ;
for(i =0 ;i <nfds;i++){
if(events[i].data.fd == sockfd){
//accect
int connfd = accept(sockfd,(sockaddr *)NULL, NULL);
if(connfd < 0){
perror("connfd < 0");
exit(1);
}
//设置用于读操作的文件描述符
ev.data.fd=connfd;
ev.events=EPOLLIN|EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev); /* 添加 */
}else{
//send read
}
}
}
}
int cpu_bind(int num){
pid_t selfid = syscall(__NR_gettid);
printf("pid :%d\n",selfid);
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(selfid % num, &mask);
sched_setaffinity(0, sizeof(mask), &mask);
}
int main(){
int sockfd = init_server();
unsigned int cpu_num = sysconf(_SC_NPROCESSORS_CONF);
printf("cup cores:%d\n",cpu_num);
int i =0;
pid_t pid =0;
for(i=0;i<cpu_num/10;i++){
pid = fork();
if(pid <= (pid_t)0){
usleep(1);
break;
}
}
if(pid > 0){//父进程
printf("running ...\n");
}else if(pid == 0){
cpu_bind(i);
main_loop(sockfd);
}
return 0;
}
上面代码只是进行简单模型实现。仅供参考