模仿nginx进行进程绑定cpu

该代码示例展示了一个简单的多进程服务器,利用epoll进行事件驱动,并通过CPU绑定提升效率。服务器监听6666端口,接受连接后,每个连接的进程绑定到一个特定的CPU核心,减少CPU上下文切换,提高系统性能。

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

为什么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;
}

上面代码只是进行简单模型实现。仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值