游双《linux高性能服务器》webserver源码

本文介绍了使用C++构建的Linux高性能服务器,通过有限状态机解析HTTP请求,利用http_conn对象跟踪每个连接状态,并采用epoll结合半同步半反应堆线程池来并发处理连接。最新更新于20210709,包括服务器启动步骤和部分源文件如locker.h、threadpool.h、http_conn.h、http_conn.cpp和main.cpp。
摘要由CSDN通过智能技术生成

有限状态机解析http请求
http_conn对象记录每一个链接的状态
epoll + 半同步半反应堆线程池并发处理连接

20210709更新:

实现方法:
(先做两个网页放进去,doc_root目录改成资源文件所在目录)

make server
./server 8888(./server + 端口号)

浏览器端:
公网ip:端口号/文件名

CXX ?= g++

DEBUG ?= 1
ifeq ($(DEBUG), 1)
    CXXFLAGS += -g
else
    CXXFLAGS += -O2

endif

server: main.cpp http_conn.cpp
	$(CXX) -o server  $^ $(CXXFLAGS) -lpthread  -g

clean:
	rm  -r server

locker.h

//线程同步机制包装类
#ifndef LOCKER_H
#define LOCKER_H

#include <exception>
#include <pthread.h>
#include <semaphore.h>

//封装信号量的类
class sem
{
   
public:
    sem()
    {
   
        if(sem_init(&m_sem, 0, 0) != 0)
        {
   
            throw std::exception();
        }
    }
    //销毁信号量
    ~sem()
    {
   
        sem_destroy(&m_sem);
    }
    //等待信号量
    bool wait()
    {
   
        return sem_wait(&m_sem) == 0;
    }
    bool post()
    {
   
        return sem_post(&m_sem) == 0;
    }
private:
    sem_t m_sem;
};


class locker
{
   
public:
    locker()
    {
   
        if(pthread_mutex_init(&m_mutex, NULL) != 0)
        {
   
            throw std::exception();
        }
    }
    ~locker()
    {
   
        pthread_mutex_destroy(&m_mutex);
    }

    bool lock()
    {
   
        return pthread_mutex_lock(&m_mutex) == 0;
    }

    bool unlock()
    {
   
        return pthread_mutex_unlock(&m_mutex) == 0;
    }

private:
    pthread_mutex_t m_mutex;

};
//phtread

class cond
{
   

public:
    cond()
    {
   
        if(pthread_mutex_init(&m_mutex, NULL) != 0)
        {
   
            throw std::exception();
        }
        if(pthread_cond_init(&m_cond, NULL) != 0)
        {
   
            //出现问题得释放已经分配的资源
            pthread_mutex_destroy(&m_mutex);
            throw std::exception();
        }
    }

    ~cond()
    {
   
        pthread_mutex_destroy(&m_mutex);
        pthread_cond_destroy(&m_cond);
    }

    bool wait()
    {
   
        int ret = 0;
        pthread_mutex_lock(&m_mutex);
        ret = pthread_cond_wait(&m_cond, &m_mutex);
        pthread_mutex_unlock(&m_mutex);
        return ret == 0;
    }

    bool signal()
    {
   
        return pthread_cond_signal(&m_cond) == 0;
    }

private:
    pthread_mutex_t m_mutex;
    pthread_cond_t m_cond;

};


#endif

threadpool.h

#ifndef THREADPOOL_H
#define THREADPOOL_H

#include <list>
#include <cstdio>
#include <exception>
#include <pthread.h>
#include "locker.h"




//线程池类,将他定义为模板类是为了代码复用
template<typename T>
class threadpool
{
   
public:
    /*thread_number是线程池中线程的数量,max_requests是请求队列中最多允许的、等待处理的请求的数量*/
    threadpool( int thread_number = 8, int max_request = 10000);
    ~threadpool();
    bool append(T *request);   

private:
    /*工作线程运行的函数,它不断从工作队列中取出任务并执行之*/
    static void *worker(void *arg);
    void run();

private:
    int m_thread_number;        //线程池中的线程数
    int m_max_requests;         //请求队列中允许的最大请求数
    pthread_t *m_threads;       //描述线程池的数组,其大小为m_thread_number
    std::list<T *> m_workqueue; //请求队列
    locker m_queuelocker;       //保护请求队列的互斥锁
    sem m_queuestat;            //是否有任务需要处理
    bool m_stop;                //是否结束线程

};
template <typename T>
threadpool<T>::threadpool(int thread_number, int max_requests) : m_thread_number(thread_number), m_max_requests(max_requests), m_stop(false),m_threads(NULL)
{
   
    printf("初始化线程池!\n");
    if (thread_number <= 0 || max_requests <= 0)
        throw std::exception();
    m_threads = new pthread_t[m_thread_number];
    if (!m_threads)
        throw std::exception();
    for (int i = 0; i < thread_number; ++i)
    {
   
        if (pthread_create(m_threads + i, NULL, worker, this) != 0)
        {
   
            delete[] m_threads;
            throw std::exception();
        }
        if (pthread_detach(m_threads[i]))
        {
   
            delete[] m_threads;
            throw std::exception();
        }
    }
}
template <typename T>
threadpool<T>::~threadpool()
{
   
    printf("线程池析构!\n");
    delete[] m_threads;
}
template <typename T>
bool threadpool<T>::append(T *request)
{
   
    printf("append()\n");
    m_queuelocker.lock();
    if (m_workqueue.size() > m_max_requests)
    {
   
        m_queuelocker.unlock();
        return false;
    }
    m_workqueue.push_back(request);
    m_queuelocker.unlock();
    m_queuestat.post();
    return true;
}
template <typename T>
void *threadpool<T>::worker(void *arg)
{
   
    printf("work()!\n");
    threadpool *pool = (threadpool *)arg;
    pool->run();
    
    return pool;
}
template <typename T>
void threadpool<T>::run()
{
   
    printf("run()!\n");
    while(!m_stop)
    {
   
        m_queuestat.wait();
        m_queuelocker.lock();
        if(m_workqueue.empty())
        {
   
            m_queuelocker.unlock();
            continue;
        }
        T * request = m_workqueue.front();
        m_workqueue.pop_front();
        m_queuelocker.unlock();
        if(!request)
        {
   
            continue;
        }
        printf("process()\n");
        request->process();
    }
}

#endif

http_conn.h

#ifndef HTTP_CONN_H
#define HTTP_CONN_H

#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值