From 220f0cdffe5446d9c0864dcd5fb3da359c2d6ac0 Mon Sep 17 00:00:00 2001 From: Zhenghao-Liu <750307817@qq.com> Date: Sat, 21 Nov 2020 18:59:52 +0800 Subject: [PATCH 1/2] fix bugs and format code and upload more information --- CGImysql/sql_connection_pool.cpp | 11 +-- CGImysql/sql_connection_pool.h | 45 ++++++++--- README.md | 4 +- config.cpp | 9 ++- config.h | 10 ++- http/http_conn.h | 101 ++++++++++++++++++++++++- lock/locker.h | 36 +++++++++ log/block_queue.h | 67 +++++++++-------- log/log.cpp | 15 ++-- log/log.h | 45 ++++++++++- main.cpp | 9 ++- threadpool/README.md | 4 +- threadpool/half-sync-reactive.bmp | Bin 0 -> 95314 bytes threadpool/threadpool.h | 31 +++++--- timer/lst_timer.cpp | 2 +- timer/lst_timer.h | 119 ++++++++++++++++++++---------- webserver.cpp | 2 +- webserver.h | 8 +- 18 files changed, 396 insertions(+), 122 deletions(-) create mode 100644 threadpool/half-sync-reactive.bmp diff --git a/CGImysql/sql_connection_pool.cpp b/CGImysql/sql_connection_pool.cpp index f4109b79..73604e01 100644 --- a/CGImysql/sql_connection_pool.cpp +++ b/CGImysql/sql_connection_pool.cpp @@ -58,7 +58,6 @@ void connection_pool::init(string url, string User, string PassWord, string DBNa m_MaxConn = m_FreeConn; } - //当有请求时,从数据库连接池中返回一个可用连接,更新使用和空闲连接数 MYSQL *connection_pool::GetConnection() { @@ -68,7 +67,7 @@ MYSQL *connection_pool::GetConnection() return NULL; reserve.wait(); - + lock.lock(); con = connList.front(); @@ -131,13 +130,15 @@ connection_pool::~connection_pool() DestroyPool(); } -connectionRAII::connectionRAII(MYSQL **SQL, connection_pool *connPool){ +connectionRAII::connectionRAII(MYSQL **SQL, connection_pool *connPool) +{ *SQL = connPool->GetConnection(); - + conRAII = *SQL; poolRAII = connPool; } -connectionRAII::~connectionRAII(){ +connectionRAII::~connectionRAII() +{ poolRAII->ReleaseConnection(conRAII); } \ No newline at end of file diff --git a/CGImysql/sql_connection_pool.h b/CGImysql/sql_connection_pool.h index 00d285be..9c4a3286 100644 --- a/CGImysql/sql_connection_pool.h +++ b/CGImysql/sql_connection_pool.h @@ -13,6 +13,26 @@ using namespace std; +/* + * m_MaxConn 最大连接数 + m_CurConn 当前已使用的连接数 + m_FreeConn 当前空闲的连接数 + connList 连接池 + * m_url 主机地址 + m_Port 数据库端口号 + m_User 登陆数据库用户名 + m_PassWord 登陆数据库密码 + m_DatabaseName 使用数据库名 + int m_close_log 日志开关 + * 单例模式:将构造写入private,通过指针进行实例化,这样保证只能实例化一次 + * 懒汉模式:需要用到创建实例了程序再去创建实例 + * GetConnection 获取数据库连接,从连接池中返回一个可用连接 + ReleaseConnection 回收连接,将连接放回连接池中 + GetFreeConn 获取当前连接池中空闲(可用)的连接数 + DestroyPool 释放连接池,即释放所有连接 + GetInstance 懒汉模式+单例模式 + init 实例化后真正的构造函数 + */ class connection_pool { public: @@ -24,34 +44,39 @@ class connection_pool //单例模式 static connection_pool *GetInstance(); - void init(string url, string User, string PassWord, string DataBaseName, int Port, int MaxConn, int close_log); + void init(string url, string User, string PassWord, string DataBaseName, int Port, int MaxConn, int close_log); private: connection_pool(); ~connection_pool(); - int m_MaxConn; //最大连接数 - int m_CurConn; //当前已使用的连接数 + int m_MaxConn; //最大连接数 + int m_CurConn; //当前已使用的连接数 int m_FreeConn; //当前空闲的连接数 locker lock; list connList; //连接池 sem reserve; public: - string m_url; //主机地址 - string m_Port; //数据库端口号 - string m_User; //登陆数据库用户名 - string m_PassWord; //登陆数据库密码 + string m_url; //主机地址 + string m_Port; //数据库端口号 + string m_User; //登陆数据库用户名 + string m_PassWord; //登陆数据库密码 string m_DatabaseName; //使用数据库名 - int m_close_log; //日志开关 + int m_close_log; //日志开关 }; -class connectionRAII{ +/* + * 采用RAII封装数据库连接池 + * RAII:是使用一个对象,在其构造时获取资源,在对象生命期控制对资源的访问使之始终保持有效,最后在对象析构的时候释放资源 + */ +class connectionRAII +{ public: connectionRAII(MYSQL **con, connection_pool *connPool); ~connectionRAII(); - + private: MYSQL *conRAII; connection_pool *poolRAII; diff --git a/README.md b/README.md index 7de0b76e..65d0caea 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ TinyWebServer =============== Linux下C++轻量级Web服务器,助力初学者快速实践网络编程,搭建属于自己的服务器. +* [测试页](http://175.24.234.48:9007) * 使用 **线程池 + 非阻塞socket + epoll(ET和LT均实现) + 事件处理(Reactor和模拟Proactor均实现)** 的并发模型 * 使用**状态机**解析HTTP请求报文,支持解析**GET和POST**请求 * 访问服务器数据库实现web端用户**注册、登录**功能,可以请求服务器**图片和视频文件** @@ -119,6 +120,7 @@ Demo演示 * 服务器测试环境 * Ubuntu版本16.04 * MySQL版本5.7.29 + * Centos 7 + MYSQL 8.0.22 * 浏览器测试环境 * Windows、Linux均可 * Chrome @@ -245,4 +247,4 @@ CPP11实现 ------------ Linux高性能服务器编程,游双著. -感谢以下朋友的PR和帮助: [@RownH](https://github.com/RownH),[@mapleFU](https://github.com/mapleFU),[@ZWiley](https://github.com/ZWiley),[@zjuHong](https://github.com/zjuHong),[@mamil](https://github.com/mamil),[@byfate](https://github.com/byfate),[@MaJun827](https://github.com/MaJun827),[@BBLiu-coder](https://github.com/BBLiu-coder),[@smoky96](https://github.com/smoky96),[@yfBong](https://github.com/yfBong),[@liuwuyao](https://github.com/liuwuyao),[@Huixxi](https://github.com/Huixxi),[@markparticle](https://github.com/markparticle). +感谢以下朋友的PR和帮助: [@RownH](https://github.com/RownH),[@mapleFU](https://github.com/mapleFU),[@ZWiley](https://github.com/ZWiley),[@zjuHong](https://github.com/zjuHong),[@mamil](https://github.com/mamil),[@byfate](https://github.com/byfate),[@MaJun827](https://github.com/MaJun827),[@BBLiu-coder](https://github.com/BBLiu-coder),[@smoky96](https://github.com/smoky96),[@yfBong](https://github.com/yfBong),[@liuwuyao](https://github.com/liuwuyao),[@Huixxi](https://github.com/Huixxi),[@markparticle](https://github.com/markparticle),[@Zhenghao-Liu](https://github.com/Zhenghao-Liu)。 diff --git a/config.cpp b/config.cpp index f16a69ec..7f3b6333 100644 --- a/config.cpp +++ b/config.cpp @@ -1,6 +1,8 @@ #include "config.h" +#include -Config::Config(){ +Config::Config() +{ //端口号,默认9006 PORT = 9006; @@ -32,7 +34,8 @@ Config::Config(){ actor_model = 0; } -void Config::parse_arg(int argc, char*argv[]){ +void Config::parse_arg(int argc, char *argv[]) +{ int opt; const char *str = "p:l:m:o:s:t:c:a:"; while ((opt = getopt(argc, argv, str)) != -1) @@ -80,7 +83,7 @@ void Config::parse_arg(int argc, char*argv[]){ break; } default: - break; + exit(EXIT_FAILURE); } } } \ No newline at end of file diff --git a/config.h b/config.h index d57db57e..eb5f7c15 100644 --- a/config.h +++ b/config.h @@ -1,3 +1,11 @@ +/* + * @Author: your name + * @Date: 2020-11-21 15:55:51 + * @LastEditTime: 2020-11-21 18:55:54 + * @LastEditors: your name + * @Description: In User Settings Edit + * @FilePath: \MiniWebServerd:\my_project\TinyWebServer\config.h + */ #ifndef CONFIG_H #define CONFIG_H @@ -11,7 +19,7 @@ class Config Config(); ~Config(){}; - void parse_arg(int argc, char*argv[]); + void parse_arg(int argc, char *argv[]); //端口号 int PORT; diff --git a/http/http_conn.h b/http/http_conn.h index b36d3652..d70b57f3 100644 --- a/http/http_conn.h +++ b/http/http_conn.h @@ -26,6 +26,102 @@ #include "../timer/lst_timer.h" #include "../log/log.h" +/* + * 线程池的工作类型类 + * FILENAME_LEN 文件名的最大长度 + READ_BUFFER_SIZE 度缓冲区的大小 + WRITE_BUFFER_SIZE 写缓冲区的大小 + METHOD HTTP请求方法 + GET 申请获取资源 + POST 客户端向服务器提交数据的方法 + HEAD 要求服务器返回头部信息 + PUT 上传某个资源 + DELETE 删除某个资源 + TRACE 要求目标服务器返回原始HTTP请求的内容 + OPTIONS 查看服务器对某个特定URL都支持哪些请求方法 + CONNECT 用于某些代理服务器,能把请求的连接转化为一个安全隧道 + PATCH 对某个资源做部分修改 + CHECK_STATE 解析客户请求时,主状态机所处的状态 + CHECK_STATE_REQUESTLINE 分析请求行 + CHECK_STATE_HEADER 分析头部域 + CHECK_STATE_CONTENT 分析消息体 + HTTP_CODE 服务器处理HTTP请求可能的结果 + NO_REQUEST 请求不完整,需要继续读取数据 + GET_REQUEST 获得了一个完整的客户请求 + BAD_REQUEST 客户请求有语法错误 + NO_RESOURCE 没有对应的资源 + FORBIDDEN_REQUEST 客户对资源没有足够访问权限 + FILE_REQUEST 客户请求是一个可读的文件 + INTERAL_ERROR 服务器内部错误 + CLOSED_CONNECTION 客户端已经关闭连接 + LINE_STATUS 行的读取状态 + LINE_OK 读取到一个完整的行 + LINE_BAD 行出错 + LINE_OPEN 行数据尚且不完整 + * init 初始化接受新的连接 + close_conn 关闭连接 + process 处理客户请求 + read_once 循环读取客户数据,知道无数据刻度或对方关闭连接 + write 非阻塞写入数据 + get_address 返回服务器端通信的socket地址 + initmysql_result 初始化mysql连接,取出数据库保存的账号和密码,存入map中 + timer_flag 是否开启了定时器 + improv + * init 初始化连接 + process_read 解析HTTP请求 + 以下一组函数被process_read调用以分析HTTP请求 + parse_request_line 解析http请求行,获得请求方法,目标url及http版本号 + parse_headers 解析http请求的一个头部信息 + parse_content 判断http请求是否被完整读入,读完消息体,这里实质上没有真正解析消息体 + do_request 当得到一个完整、正确的HTTP请求时,分析用户的请求内容:登陆、注册、获取文件 + get_line 移动指针读取一行 + parse_line 从状态机,用于分析出一行内容 + process_write 填充HTTP应答 + 以下一组函数被process_write调用用以填充HTTP应答 + unmap 释放共享内存映射区 + add_response 往HTTP应答中写入待发送的数据 + add_content 往HTTP应答写入消息体 + add_status_line 往HTTP应答写入状态行 + add_content_type 往HTTP应答写入头部字段的目标文档的MIME类型 + add_content_length 往HTTP应答写入头部字段的目标文档的长度 + add_linger 往HTTP应答写入头部字段的此次通信后是否关闭TCP连接 + add_blank_line 往HTTP应答写入一个空行 \r\n + * m_pollfd epoll的事件表文件描述符 + m_user_count 统计用户数量 + mysql 连接的数据库 + m_state 读为0,写为1 + * m_sockfd HTTP连接的socket文件描述符 + m_address HTTP对方的socket地址 + m_read_buf 读缓冲区 + m_read_idx 表示读缓冲中已经读入的客户数据的最后一个字节的下一个位置 + m_check_idx 当前正在分析的字符在读缓冲区中的位置 + m_start_line 当前正在解析的行的起始位置 + m_write_buf 写缓冲区 + m_write_idx 写缓冲区中待发送的字节数 + m_check_state 主状态机当前所处的状态 + m_method 请求方法 + m_real_file 客户请求的目标文件的完整路径,其内容等于网站根目录doc_root+m_url + m_url 客户请求的目标文件的文件名 + m_version HTTP 协议版本号,此程序只支持HTTP/1.1 + m_host 主机名 + m_content_length HTTP请求的消息体的长度 + m_linger HTTP其你去是否要求保持连接 + m_file_address 客户请求的目标文件被mmap到内存中的起始位置 + m_file_stat 目标文件的状态:是否存在、是否为目录、是否刻度、文件信息 + m_iv 采用writev写操作的内存分块 + m_iv_count 采用writev写操作的内存分块数量 + cgi 是否启用新的POST + m_string 存储请求头数据 + bytes_to_send 需要发送的字节数 + bytes_have_send 已经发送的字节数 + doc_root 服务器端网站根目录 + m_users 客户账号和密码 + m_TRIGMode 是否采用ET工作模式 + m_close_log 是否关闭日志功能 + sql_uesr MYSQL用户名 + sql_passwd MYSQL密码 + sql_name MYSQL数据库名 + */ class http_conn { public: @@ -42,7 +138,7 @@ class http_conn TRACE, OPTIONS, CONNECT, - PATH + PATCH }; enum CHECK_STATE { @@ -86,7 +182,6 @@ class http_conn int timer_flag; int improv; - private: void init(); HTTP_CODE process_read(); @@ -111,7 +206,7 @@ class http_conn static int m_epollfd; static int m_user_count; MYSQL *mysql; - int m_state; //读为0, 写为1 + int m_state; //读为0, 写为1 private: int m_sockfd; diff --git a/lock/locker.h b/lock/locker.h index de38a06e..3ed9d3f0 100644 --- a/lock/locker.h +++ b/lock/locker.h @@ -5,6 +5,13 @@ #include #include +/* + * 封装信号量的类 + * sem_init函数用于初始化一个未命名的信号量 + * sem_destory函数用于销毁信号量 + * sem_wait函数将以原子操作方式将信号量减一,信号量为0时,sem_wait阻塞 + * sem_post函数以原子操作方式将信号量加一,信号量大于0时,唤醒调用sem_post的线程 + */ class sem { public: @@ -38,6 +45,14 @@ class sem private: sem_t m_sem; }; + +/* + * 封装互斥锁的类 + * pthread_mutex_init函数用于初始化互斥锁 + * pthread_mutex_destory函数用于销毁互斥锁 + * pthread_mutex_lock函数以原子操作方式给互斥锁加锁 + * pthread_mutex_unlock函数以原子操作方式给互斥锁解锁 + */ class locker { public: @@ -68,6 +83,19 @@ class locker private: pthread_mutex_t m_mutex; }; + +/* + * 封装条件变量的类,此类与书本上的实现有所不同 + * 与条件变量协作的互斥锁不是封装在类里,而是以参数形式传入 + * pthread_cond_init函数用于初始化条件变量 + * pthread_cond_destory函数销毁条件变量 + * pthread_cond_wait函数用于等待目标条件变量.该函数调用时需要传入 mutex参数(必须是一个已经加锁的互斥锁), + 函数执行时,先把调用线程放入条件变量的请求队列,然后将互斥锁mutex解锁,当函数成功返回为0时,互斥锁会再次被锁上. + 也就是说函数内部会有一次解锁和加锁操作. + * pthread_cond_broadcast函数以广播的方式唤醒所有等待目标条件变量的线程 + * pthread_cond_signal函数用于唤醒一个等待目标条件变量的线程, + 至于哪个线程被唤醒,则取决于线程的优先级和调度策略 + */ class cond { public: @@ -83,6 +111,14 @@ class cond { pthread_cond_destroy(&m_cond); } + /* + * 参数m_mutex必须是一个已经上锁的互斥变量 + * 如果m_mutex的type是一个PTHREAD_MUTEX_NORMAL普通锁 + 可以通过pthread_mutex_trylock的方式判断返回值来检测原先是否已经加锁 + 别忘了如果trylock成功要记得解锁 + * 但是涉及到pthread_mutex_t的属性type还有别的类型的锁 + * 只能将安全性结果交给函数外保证 + */ bool wait(pthread_mutex_t *m_mutex) { int ret = 0; diff --git a/log/block_queue.h b/log/block_queue.h index 34c77bd5..ad67ac0b 100644 --- a/log/block_queue.h +++ b/log/block_queue.h @@ -13,6 +13,19 @@ #include "../lock/locker.h" using namespace std; +/* + * 将生产者-消费者模型封装为阻塞队列,创建一个写线程, + * 工作线程将要写的内容push进队列,写线程从队列中取出内容,写入日志文件 + * 用一个循环数组来模拟队列 + * m_mutex 互斥锁 + cond 条件变量 + m_array 队列实例化后的元素类型 + m_size 队列当前实际使用大小 + m_max_size 队列最大容量 + m_front 指向队列的头指针 + m_back 指向队列的尾指针,采取左闭右闭[m_front,m_back] + * m_back = (m_back + 1) % m_max_size; 将事件增加到队尾 + */ template class block_queue { @@ -44,12 +57,12 @@ class block_queue { m_mutex.lock(); if (m_array != NULL) - delete [] m_array; + delete[] m_array; m_mutex.unlock(); } //判断队列是否满了 - bool full() + bool full() { m_mutex.lock(); if (m_size >= m_max_size) @@ -62,7 +75,7 @@ class block_queue return false; } //判断队列是否为空 - bool empty() + bool empty() { m_mutex.lock(); if (0 == m_size) @@ -74,7 +87,7 @@ class block_queue return false; } //返回队首元素 - bool front(T &value) + bool front(T &value) { m_mutex.lock(); if (0 == m_size) @@ -87,7 +100,7 @@ class block_queue return true; } //返回队尾元素 - bool back(T &value) + bool back(T &value) { m_mutex.lock(); if (0 == m_size) @@ -100,7 +113,7 @@ class block_queue return true; } - int size() + int size() { int tmp = 0; @@ -124,76 +137,70 @@ class block_queue //往队列添加元素,需要将所有使用队列的线程先唤醒 //当有元素push进队列,相当于生产者生产了一个元素 //若当前没有线程等待条件变量,则唤醒无意义 - bool push(const T &item) + bool push(const T &in_elem) { - m_mutex.lock(); if (m_size >= m_max_size) { - m_cond.broadcast(); m_mutex.unlock(); return false; } - - m_back = (m_back + 1) % m_max_size; - m_array[m_back] = item; - - m_size++; - + if (m_back == -1 && m_front == -1) + { + m_back = 0; + m_front = 0; + } + else + m_back = (m_back + 1) % m_max_size; + m_array[m_back] = in_elem; + ++m_size; m_cond.broadcast(); m_mutex.unlock(); return true; } //pop时,如果当前队列没有元素,将会等待条件变量 - bool pop(T &item) + bool pop(T &out_elem) { - m_mutex.lock(); while (m_size <= 0) - { - if (!m_cond.wait(m_mutex.get())) { m_mutex.unlock(); return false; } - } - + out_elem = m_array[m_front]; m_front = (m_front + 1) % m_max_size; - item = m_array[m_front]; - m_size--; + --m_size; m_mutex.unlock(); return true; } //增加了超时处理 - bool pop(T &item, int ms_timeout) + bool pop(T &out_elem, int ms_timeout) { - struct timespec t = {0, 0}; struct timeval now = {0, 0}; gettimeofday(&now, NULL); + struct timespec t = {0, 0}; m_mutex.lock(); if (m_size <= 0) { t.tv_sec = now.tv_sec + ms_timeout / 1000; - t.tv_nsec = (ms_timeout % 1000) * 1000; + t.tv_nsec = (now.tv_usec + (ms_timeout % 1000) * 1000) * 1000; if (!m_cond.timewait(m_mutex.get(), t)) { m_mutex.unlock(); return false; } } - if (m_size <= 0) { m_mutex.unlock(); return false; } - + out_elem = m_array[m_front]; m_front = (m_front + 1) % m_max_size; - item = m_array[m_front]; - m_size--; + --m_size; m_mutex.unlock(); return true; } diff --git a/log/log.cpp b/log/log.cpp index 65e8ad46..93ce3ab6 100644 --- a/log/log.cpp +++ b/log/log.cpp @@ -31,7 +31,7 @@ bool Log::init(const char *file_name, int close_log, int log_buf_size, int split //flush_log_thread为回调函数,这里表示创建线程异步写日志 pthread_create(&tid, NULL, flush_log_thread, NULL); } - + m_close_log = close_log; m_log_buf_size = log_buf_size; m_buf = new char[m_log_buf_size]; @@ -42,7 +42,6 @@ bool Log::init(const char *file_name, int close_log, int log_buf_size, int split struct tm *sys_tm = localtime(&t); struct tm my_tm = *sys_tm; - const char *p = strrchr(file_name, '/'); char log_full_name[256] = {0}; @@ -58,7 +57,7 @@ bool Log::init(const char *file_name, int close_log, int log_buf_size, int split } m_today = my_tm.tm_mday; - + m_fp = fopen(log_full_name, "a"); if (m_fp == NULL) { @@ -100,14 +99,14 @@ void Log::write_log(int level, const char *format, ...) if (m_today != my_tm.tm_mday || m_count % m_split_lines == 0) //everyday log { - + char new_log[256] = {0}; fflush(m_fp); fclose(m_fp); char tail[16] = {0}; - + snprintf(tail, 16, "%d_%02d_%02d_", my_tm.tm_year + 1900, my_tm.tm_mon + 1, my_tm.tm_mday); - + if (m_today != my_tm.tm_mday) { snprintf(new_log, 255, "%s%s%s", dir_name, tail, log_name); @@ -120,7 +119,7 @@ void Log::write_log(int level, const char *format, ...) } m_fp = fopen(new_log, "a"); } - + m_mutex.unlock(); va_list valst; @@ -133,7 +132,7 @@ void Log::write_log(int level, const char *format, ...) int n = snprintf(m_buf, 48, "%d-%02d-%02d %02d:%02d:%02d.%06ld %s ", my_tm.tm_year + 1900, my_tm.tm_mon + 1, my_tm.tm_mday, my_tm.tm_hour, my_tm.tm_min, my_tm.tm_sec, now.tv_usec, s); - + int m = vsnprintf(m_buf + n, m_log_buf_size - 1, format, valst); m_buf[n + m] = '\n'; m_buf[n + m + 1] = '\0'; diff --git a/log/log.h b/log/log.h index 64972af4..39175463 100644 --- a/log/log.h +++ b/log/log.h @@ -10,6 +10,23 @@ using namespace std; +/* + * dir_name 路径名 + log_name 日志文件名 + m_split_lines 日志最大行数 + m_log_bug_size 日志缓冲区大小 + m_count 日志当前已用行数 + m_today 当前时间是哪一天 + m_fp 打开log的文件指针 + m_buf 缓冲区指针 + m_log_queue 阻塞队列 + m_is_async 是否同步标志位 + m_mutex 互斥锁 + m_clog_log 是否关闭日志 + * 单例模式:将构造写入private,通过指针进行实例化,这样保证只能实例化一次 + * 懒汉模式:需要用到创建实例了程序再去创建实例 + * async_write_log 同步的从消息队列中取出消息,写入日志文件中 + */ class Log { public: @@ -61,9 +78,29 @@ class Log int m_close_log; //关闭日志 }; -#define LOG_DEBUG(format, ...) if(0 == m_close_log) {Log::get_instance()->write_log(0, format, ##__VA_ARGS__); Log::get_instance()->flush();} -#define LOG_INFO(format, ...) if(0 == m_close_log) {Log::get_instance()->write_log(1, format, ##__VA_ARGS__); Log::get_instance()->flush();} -#define LOG_WARN(format, ...) if(0 == m_close_log) {Log::get_instance()->write_log(2, format, ##__VA_ARGS__); Log::get_instance()->flush();} -#define LOG_ERROR(format, ...) if(0 == m_close_log) {Log::get_instance()->write_log(3, format, ##__VA_ARGS__); Log::get_instance()->flush();} +#define LOG_DEBUG(format, ...) \ + if (0 == m_close_log) \ + { \ + Log::get_instance()->write_log(0, format, ##__VA_ARGS__); \ + Log::get_instance()->flush(); \ + } +#define LOG_INFO(format, ...) \ + if (0 == m_close_log) \ + { \ + Log::get_instance()->write_log(1, format, ##__VA_ARGS__); \ + Log::get_instance()->flush(); \ + } +#define LOG_WARN(format, ...) \ + if (0 == m_close_log) \ + { \ + Log::get_instance()->write_log(2, format, ##__VA_ARGS__); \ + Log::get_instance()->flush(); \ + } +#define LOG_ERROR(format, ...) \ + if (0 == m_close_log) \ + { \ + Log::get_instance()->write_log(3, format, ##__VA_ARGS__); \ + Log::get_instance()->flush(); \ + } #endif diff --git a/main.cpp b/main.cpp index 19a4fff7..4e7b5268 100644 --- a/main.cpp +++ b/main.cpp @@ -1,7 +1,11 @@ #include "config.h" +#include int main(int argc, char *argv[]) { + //将下句代码取消注释即可将此程序以守护进程运行 + //daemon(1,0); + //需要修改的数据库信息,登录名,密码,库名 string user = "root"; string passwd = "root"; @@ -14,10 +18,9 @@ int main(int argc, char *argv[]) WebServer server; //初始化 - server.init(config.PORT, user, passwd, databasename, config.LOGWrite, - config.OPT_LINGER, config.TRIGMode, config.sql_num, config.thread_num, + server.init(config.PORT, user, passwd, databasename, config.LOGWrite, + config.OPT_LINGER, config.TRIGMode, config.sql_num, config.thread_num, config.close_log, config.actor_model); - //日志 server.log_write(); diff --git a/threadpool/README.md b/threadpool/README.md index f015fb02..9942919a 100644 --- a/threadpool/README.md +++ b/threadpool/README.md @@ -1,4 +1,4 @@ - + 半同步/半反应堆线程池 =============== 使用一个工作队列完全解除了主线程和工作线程的耦合关系:主线程往工作队列中插入任务,工作线程通过竞争来取得任务并执行它。 @@ -6,7 +6,7 @@ > * 半同步/半反应堆 > * 线程池 - +![image](./half-sync-reactive.bmp) diff --git a/threadpool/half-sync-reactive.bmp b/threadpool/half-sync-reactive.bmp new file mode 100644 index 0000000000000000000000000000000000000000..865a917b4ff90bb7bb0c43ccc5dd879f9f9c7c6c GIT binary patch literal 95314 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 g@6-O@wA class threadpool { @@ -24,17 +37,17 @@ class threadpool void run(); private: - int m_thread_number; //线程池中的线程数 - int m_max_requests; //请求队列中允许的最大请求数 - pthread_t *m_threads; //描述线程池的数组,其大小为m_thread_number - std::list m_workqueue; //请求队列 - locker m_queuelocker; //保护请求队列的互斥锁 - sem m_queuestat; //是否有任务需要处理 - connection_pool *m_connPool; //数据库 - int m_actor_model; //模型切换 + int m_thread_number; //线程池中的线程数 + int m_max_requests; //请求队列中允许的最大请求数 + pthread_t *m_threads; //描述线程池的数组,其大小为m_thread_number + std::list m_workqueue; //请求队列 + locker m_queuelocker; //保护请求队列的互斥锁 + sem m_queuestat; //是否有任务需要处理 + connection_pool *m_connPool; //数据库 + int m_actor_model; //模型切换 }; template -threadpool::threadpool( int actor_model, connection_pool *connPool, int thread_number, int max_requests) : m_actor_model(actor_model),m_thread_number(thread_number), m_max_requests(max_requests), m_threads(NULL),m_connPool(connPool) +threadpool::threadpool(int actor_model, connection_pool *connPool, int thread_number, int max_requests) : m_actor_model(actor_model), m_thread_number(thread_number), m_max_requests(max_requests), m_threads(NULL), m_connPool(connPool) { if (thread_number <= 0 || max_requests <= 0) throw std::exception(); diff --git a/timer/lst_timer.cpp b/timer/lst_timer.cpp index 7efba9bd..e3f0b8cc 100644 --- a/timer/lst_timer.cpp +++ b/timer/lst_timer.cpp @@ -99,7 +99,7 @@ void sort_timer_lst::tick() { return; } - + time_t cur = time(NULL); util_timer *tmp = head; while (tmp) diff --git a/timer/lst_timer.h b/timer/lst_timer.h index 5a64c7fa..9f407816 100644 --- a/timer/lst_timer.h +++ b/timer/lst_timer.h @@ -24,77 +24,122 @@ #include #include "../log/log.h" +/* + * 前向声明:两个元素之前互相调用,但是因为声明顺序的关系, + 导致一个元素找不到另一个元素的声明,所以要提前声明 + */ class util_timer; +/* + * 用户数据结构 + * address 客户端socket地址 + sockfd 客户端对应的socket文件描述符 + timer 定时器 + */ struct client_data { - sockaddr_in address; - int sockfd; - util_timer *timer; + sockaddr_in address; + int sockfd; + util_timer *timer; }; +/* + * 定时器类 + * expire 任务的超时时间,这里设定为绝对时间,即Unix时间,以s为单位 + user_data 指向用户数据 + prev 指向前一个定时器 + next 指向下一个定时器 + cb_func 定时器回调函数(要执行的函数) + */ class util_timer { public: - util_timer() : prev(NULL), next(NULL) {} + util_timer() : prev(NULL), next(NULL) {} public: - time_t expire; - - void (* cb_func)(client_data *); - client_data *user_data; - util_timer *prev; - util_timer *next; + time_t expire; + + void (*cb_func)(client_data *); + client_data *user_data; + util_timer *prev; + util_timer *next; }; +/* + * 定时器链表 + 一个按照过期时间升序,双向链表,且带有头尾指针 + * head 头指针指向第一个定时器 + tail 尾指针指向最后一个定时器 + private:add_timer 一个重载的辅助函数,被public的add_timer和adjust_timer函数调用, + 该函数用于将timer添加到节点lst_head之后的部分链表中 + * add_timer 将定时器添加到链表中 + adjust_timer 修改链表中的某个定时器,只支持过期时间延长 + del_timer 将定时器从链表中删除 + tick SIGALRM信号被触发,即有任务到期,执行此函数处理链表上所有到期的任务 + */ class sort_timer_lst { public: - sort_timer_lst(); - ~sort_timer_lst(); + sort_timer_lst(); + ~sort_timer_lst(); - void add_timer(util_timer *timer); - void adjust_timer(util_timer *timer); - void del_timer(util_timer *timer); - void tick(); + void add_timer(util_timer *timer); + void adjust_timer(util_timer *timer); + void del_timer(util_timer *timer); + void tick(); private: - void add_timer(util_timer *timer, util_timer *lst_head); + void add_timer(util_timer *timer, util_timer *lst_head); - util_timer *head; - util_timer *tail; + util_timer *head; + util_timer *tail; }; +/* + * 封装客户类 + * u_pipefd 通信的管道 + m_timer_lst 定时器链表 + u_epollfd epoll事件表的文件描述符 + m_TIMESLOT 设定一个定时时间触发SIGALRM信号 + * init 初始化 + setnonblocking 对文件描述符设置非阻塞 + 因为epoll采用ET边沿触发,如果是阻塞的,socket的读写操作将会因为没有后续的事件而一直处于阻塞状态 + addfd 将事件添加到epoll时间表中,根据判断TRIGMode==1决定是否开启ET工作模式 + sig_handler 信号处理函数 + addsig 设置信号对应的信号处理函数 + timer_handler 定时处理超时的任务,并通过alarm重新定时以不断触发SIGALRM信号 + show_error 向客户端发送错误信息,并关闭该连接 + */ class Utils { public: - Utils() {} - ~Utils() {} + Utils() {} + ~Utils() {} - void init(int timeslot); + void init(int timeslot); - //对文件描述符设置非阻塞 - int setnonblocking(int fd); + //对文件描述符设置非阻塞 + int setnonblocking(int fd); - //将内核事件表注册读事件,ET模式,选择开启EPOLLONESHOT - void addfd(int epollfd, int fd, bool one_shot, int TRIGMode); + //将内核事件表注册读事件,ET模式,选择开启EPOLLONESHOT + void addfd(int epollfd, int fd, bool one_shot, int TRIGMode); - //信号处理函数 - static void sig_handler(int sig); + //信号处理函数 + static void sig_handler(int sig); - //设置信号函数 - void addsig(int sig, void(handler)(int), bool restart = true); + //设置信号函数 + void addsig(int sig, void(handler)(int), bool restart = true); - //定时处理任务,重新定时以不断触发SIGALRM信号 - void timer_handler(); + //定时处理任务,重新定时以不断触发SIGALRM信号 + void timer_handler(); - void show_error(int connfd, const char *info); + void show_error(int connfd, const char *info); public: - static int *u_pipefd; - sort_timer_lst m_timer_lst; - static int u_epollfd; - int m_TIMESLOT; + static int *u_pipefd; + sort_timer_lst m_timer_lst; + static int u_epollfd; + int m_TIMESLOT; }; void cb_func(client_data *user_data); diff --git a/webserver.cpp b/webserver.cpp index a9dfae0b..31420218 100644 --- a/webserver.cpp +++ b/webserver.cpp @@ -28,7 +28,7 @@ WebServer::~WebServer() delete m_pool; } -void WebServer::init(int port, string user, string passWord, string databaseName, int log_write, +void WebServer::init(int port, string user, string passWord, string databaseName, int log_write, int opt_linger, int trigmode, int sql_num, int thread_num, int close_log, int actor_model) { m_port = port; diff --git a/webserver.h b/webserver.h index 7381a13e..942fc7da 100644 --- a/webserver.h +++ b/webserver.h @@ -1,4 +1,4 @@ -#ifndef WEBSERVER_H +ifndef WEBSERVER_H #define WEBSERVER_H #include @@ -25,8 +25,8 @@ class WebServer WebServer(); ~WebServer(); - void init(int port , string user, string passWord, string databaseName, - int log_write , int opt_linger, int trigmode, int sql_num, + void init(int port, string user, string passWord, string databaseName, + int log_write, int opt_linger, int trigmode, int sql_num, int thread_num, int close_log, int actor_model); void thread_pool(); @@ -39,7 +39,7 @@ class WebServer void adjust_timer(util_timer *timer); void deal_timer(util_timer *timer, int sockfd); bool dealclinetdata(); - bool dealwithsignal(bool& timeout, bool& stop_server); + bool dealwithsignal(bool &timeout, bool &stop_server); void dealwithread(int sockfd); void dealwithwrite(int sockfd); From 0fcaf6feb9ffd8dd9b1b3c64ef7309b3859f6143 Mon Sep 17 00:00:00 2001 From: Zhenghao-Liu <750307817@qq.com> Date: Sat, 21 Nov 2020 19:03:43 +0800 Subject: [PATCH 2/2] fix mistake --- config.h | 8 -------- webserver.h | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/config.h b/config.h index eb5f7c15..b118f4eb 100644 --- a/config.h +++ b/config.h @@ -1,11 +1,3 @@ -/* - * @Author: your name - * @Date: 2020-11-21 15:55:51 - * @LastEditTime: 2020-11-21 18:55:54 - * @LastEditors: your name - * @Description: In User Settings Edit - * @FilePath: \MiniWebServerd:\my_project\TinyWebServer\config.h - */ #ifndef CONFIG_H #define CONFIG_H diff --git a/webserver.h b/webserver.h index 942fc7da..8e891cf2 100644 --- a/webserver.h +++ b/webserver.h @@ -1,4 +1,4 @@ -ifndef WEBSERVER_H +#ifndef WEBSERVER_H #define WEBSERVER_H #include