文章目录
- 一、安装libevent
- 二、安装jsoncpp
- 三、http多线程服务
一、安装libevent
下载编译安装,提前安装好gcc, make
sudo su
yum -y install wget
wget http://www.monkey.org/~provos/libevent-2.0.10-stable.tar.gz
tar -zxvf libevent-2.0.10-stable.tar.gz
cd libevent-2.0.10-stable
./configure --prefix=/usr
make -j2
make install# 查看安装结果
ls -al /usr/lib | grep libevent
安装后的输出信息,
make install-recursive
make[1]: Entering directory `/home/username/libevent-2.0.10-stable'
Making install in .
make[2]: Entering directory `/home/username/libevent-2.0.10-stable'
make[3]: Entering directory `/home/username/libevent-2.0.10-stable'
test -z "/usr/bin" || /usr/bin/mkdir -p "/usr/bin"/usr/bin/install -c event_rpcgen.py '/usr/bin'
test -z "/usr/lib" || /usr/bin/mkdir -p "/usr/lib"/bin/sh ./libtool --mode=install /usr/bin/install -c libevent.la libevent_core.la libevent_extra.la libevent_pthreads.la libevent_openssl.la '/usr/lib'
libtool: install: /usr/bin/install -c .libs/libevent-2.0.so.5.0.1 /usr/lib/libevent-2.0.so.5.0.1
libtool: install: (cd /usr/lib && { ln -s -f libevent-2.0.so.5.0.1 libevent-2.0.so.5 || { rm -f libevent-2.0.so.5 && ln -s libevent-2.0.so.5.0.1 libevent-2.0.so.5; }; })
libtool: install: (cd /usr/lib && { ln -s -f libevent-2.0.so.5.0.1 libevent.so || { rm -f libevent.so && ln -s libevent-2.0.so.5.0.1 libevent.so; }; })
libtool: install: /usr/bin/install -c .libs/libevent.lai /usr/lib/libevent.la
libtool: install: /usr/bin/install -c .libs/libevent_core-2.0.so.5.0.1 /usr/lib/libevent_core-2.0.so.5.0.1
libtool: install: (cd /usr/lib && { ln -s -f libevent_core-2.0.so.5.0.1 libevent_core-2.0.so.5 || { rm -f libevent_core-2.0.so.5 && ln -s libevent_core-2.0.so.5.0.1 libevent_core-2.0.so.5; }; })
libtool: install: (cd /usr/lib && { ln -s -f libevent_core-2.0.so.5.0.1 libevent_core.so || { rm -f libevent_core.so && ln -s libevent_core-2.0.so.5.0.1 libevent_core.so; }; })
libtool: install: /usr/bin/install -c .libs/libevent_core.lai /usr/lib/libevent_core.la
libtool: install: /usr/bin/install -c .libs/libevent_extra-2.0.so.5.0.1 /usr/lib/libevent_extra-2.0.so.5.0.1
libtool: install: (cd /usr/lib && { ln -s -f libevent_extra-2.0.so.5.0.1 libevent_extra-2.0.so.5 || { rm -f libevent_extra-2.0.so.5 && ln -s libevent_extra-2.0.so.5.0.1 libevent_extra-2.0.so.5; }; })
libtool: install: (cd /usr/lib && { ln -s -f libevent_extra-2.0.so.5.0.1 libevent_extra.so || { rm -f libevent_extra.so && ln -s libevent_extra-2.0.so.5.0.1 libevent_extra.so; }; })
libtool: install: /usr/bin/install -c .libs/libevent_extra.lai /usr/lib/libevent_extra.la
libtool: install: /usr/bin/install -c .libs/libevent_pthreads-2.0.so.5.0.1 /usr/lib/libevent_pthreads-2.0.so.5.0.1
libtool: install: (cd /usr/lib && { ln -s -f libevent_pthreads-2.0.so.5.0.1 libevent_pthreads-2.0.so.5 || { rm -f libevent_pthreads-2.0.so.5 && ln -s libevent_pthreads-2.0.so.5.0.1 libevent_pthreads-2.0.so.5; }; })
libtool: install: (cd /usr/lib && { ln -s -f libevent_pthreads-2.0.so.5.0.1 libevent_pthreads.so || { rm -f libevent_pthreads.so && ln -s libevent_pthreads-2.0.so.5.0.1 libevent_pthreads.so; }; })
libtool: install: /usr/bin/install -c .libs/libevent_pthreads.lai /usr/lib/libevent_pthreads.la
libtool: install: /usr/bin/install -c .libs/libevent_openssl-2.0.so.5.0.1 /usr/lib/libevent_openssl-2.0.so.5.0.1
libtool: install: (cd /usr/lib && { ln -s -f libevent_openssl-2.0.so.5.0.1 libevent_openssl-2.0.so.5 || { rm -f libevent_openssl-2.0.so.5 && ln -s libevent_openssl-2.0.so.5.0.1 libevent_openssl-2.0.so.5; }; })
libtool: install: (cd /usr/lib && { ln -s -f libevent_openssl-2.0.so.5.0.1 libevent_openssl.so || { rm -f libevent_openssl.so && ln -s libevent_openssl-2.0.so.5.0.1 libevent_openssl.so; }; })
libtool: install: /usr/bin/install -c .libs/libevent_openssl.lai /usr/lib/libevent_openssl.la
libtool: install: /usr/bin/install -c .libs/libevent.a /usr/lib/libevent.a
libtool: install: chmod 644 /usr/lib/libevent.a
libtool: install: ranlib /usr/lib/libevent.a
libtool: install: /usr/bin/install -c .libs/libevent_core.a /usr/lib/libevent_core.a
libtool: install: chmod 644 /usr/lib/libevent_core.a
libtool: install: ranlib /usr/lib/libevent_core.a
libtool: install: /usr/bin/install -c .libs/libevent_extra.a /usr/lib/libevent_extra.a
libtool: install: chmod 644 /usr/lib/libevent_extra.a
libtool: install: ranlib /usr/lib/libevent_extra.a
libtool: install: /usr/bin/install -c .libs/libevent_pthreads.a /usr/lib/libevent_pthreads.a
libtool: install: chmod 644 /usr/lib/libevent_pthreads.a
libtool: install: ranlib /usr/lib/libevent_pthreads.a
libtool: install: /usr/bin/install -c .libs/libevent_openssl.a /usr/lib/libevent_openssl.a
libtool: install: chmod 644 /usr/lib/libevent_openssl.a
libtool: install: ranlib /usr/lib/libevent_openssl.a
libtool: finish: PATH="/opt/rh/devtoolset-8/root/usr/bin:/home/username/cmake-3.23.4-linux-x86_64/bin:/opt/rh/devtoolset-8/root/usr/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/username/.local/bin:/home/username/bin:/sbin" ldconfig -n /usr/lib
----------------------------------------------------------------------
Libraries have been installed in:/usr/libIf you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:- add LIBDIR to the `LD_LIBRARY_PATH' environment variableduring execution- add LIBDIR to the `LD_RUN_PATH' environment variableduring linking- use the `-Wl,-rpath -Wl,LIBDIR' linker flag- have your system administrator add LIBDIR to `/etc/ld.so.conf'See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
[username@localhost libevent-2.0.10-stable]$ ls -al /usr/lib | grep libevent
lrwxrwxrwx. 1 root root 21 Jul 26 13:26 libevent-2.0.so.5 -> libevent-2.0.so.5.0.1
-rwxr-xr-x. 1 root root 1246224 Jul 26 13:26 libevent-2.0.so.5.0.1
-rw-r--r--. 1 root root 2204618 Jul 26 13:26 libevent.a
lrwxrwxrwx. 1 root root 26 Jul 26 13:26 libevent_core-2.0.so.5 -> libevent_core-2.0.so.5.0.1
-rwxr-xr-x. 1 root root 770744 Jul 26 13:26 libevent_core-2.0.so.5.0.1
-rw-r--r--. 1 root root 1323706 Jul 26 13:26 libevent_core.a
-rwxr-xr-x. 1 root root 975 Jul 26 13:26 libevent_core.la
lrwxrwxrwx. 1 root root 26 Jul 26 13:26 libevent_core.so -> libevent_core-2.0.so.5.0.1
lrwxrwxrwx. 1 root root 27 Jul 26 13:26 libevent_extra-2.0.so.5 -> libevent_extra-2.0.so.5.0.1
-rwxr-xr-x. 1 root root 501664 Jul 26 13:26 libevent_extra-2.0.so.5.0.1
-rw-r--r--. 1 root root 880986 Jul 26 13:26 libevent_extra.a
-rwxr-xr-x. 1 root root 982 Jul 26 13:26 libevent_extra.la
lrwxrwxrwx. 1 root root 27 Jul 26 13:26 libevent_extra.so -> libevent_extra-2.0.so.5.0.1
-rwxr-xr-x. 1 root root 940 Jul 26 13:26 libevent.la
lrwxrwxrwx. 1 root root 29 Jul 26 13:26 libevent_openssl-2.0.so.5 -> libevent_openssl-2.0.so.5.0.1
-rwxr-xr-x. 1 root root 117392 Jul 26 13:26 libevent_openssl-2.0.so.5.0.1
-rw-r--r--. 1 root root 217556 Jul 26 13:26 libevent_openssl.a
-rwxr-xr-x. 1 root root 1011 Jul 26 13:26 libevent_openssl.la
lrwxrwxrwx. 1 root root 29 Jul 26 13:26 libevent_openssl.so -> libevent_openssl-2.0.so.5.0.1
lrwxrwxrwx. 1 root root 30 Jul 26 13:26 libevent_pthreads-2.0.so.5 -> libevent_pthreads-2.0.so.5.0.1
-rwxr-xr-x. 1 root root 26440 Jul 26 13:26 libevent_pthreads-2.0.so.5.0.1
-rw-r--r--. 1 root root 26454 Jul 26 13:26 libevent_pthreads.a
-rwxr-xr-x. 1 root root 1003 Jul 26 13:26 libevent_pthreads.la
lrwxrwxrwx. 1 root root 30 Jul 26 13:26 libevent_pthreads.so -> libevent_pthreads-2.0.so.5.0.1
lrwxrwxrwx. 1 root root 21 Jul 26 13:26 libevent.so -> libevent-2.0.so.5.0.1
二、安装jsoncpp
开源地址:https://github.com/open-source-parsers/jsoncpp
wget https://github.com/open-source-parsers/jsoncpp/archive/refs/tags/1.9.4.tar.gz
tar -zxvf 1.9.4.tar.gz
cd jsoncpp-1.9.4/
mkdir build && cd build/cmake -DCMAKE_BUILD_TYPE=release \
-DBUILD_STATIC_LIBS=ON \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_INSTALL_INCLUDEDIR=/usr/include/jsoncpp \
-DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" ../make -j2
sudo make install
[username@localhost build]$ sudo make install
[sudo] password for username:
Consolidate compiler generated dependencies of target jsoncpp_lib
[ 23%] Built target jsoncpp_lib
Consolidate compiler generated dependencies of target jsoncpp_static
[ 47%] Built target jsoncpp_static
Consolidate compiler generated dependencies of target jsoncpp_object
[ 64%] Built target jsoncpp_object
Consolidate compiler generated dependencies of target jsontestrunner_exe
[ 76%] Built target jsontestrunner_exe
Consolidate compiler generated dependencies of target jsoncpp_test
[100%] Built target jsoncpp_test
Install the project...
-- Install configuration: "release"
-- Installing: /usr/local/lib64/pkgconfig/jsoncpp.pc
-- Installing: /usr/local/lib64/cmake/jsoncpp/jsoncppConfig.cmake
-- Installing: /usr/local/lib64/cmake/jsoncpp/jsoncppConfig-release.cmake
-- Installing: /usr/local/lib64/cmake/jsoncpp/jsoncppConfigVersion.cmake
-- Installing: /usr/local/lib64/libjsoncpp.so.1.9.4
-- Installing: /usr/local/lib64/libjsoncpp.so.24
-- Installing: /usr/local/lib64/libjsoncpp.so
-- Installing: /usr/local/lib64/libjsoncpp_static.a
-- Installing: /usr/local/lib64/objects-release/jsoncpp_object/json_reader.cpp.o
-- Installing: /usr/local/lib64/objects-release/jsoncpp_object/json_value.cpp.o
-- Installing: /usr/local/lib64/objects-release/jsoncpp_object/json_writer.cpp.o
-- Installing: /usr/include/jsoncpp/json/allocator.h
-- Installing: /usr/include/jsoncpp/json/assertions.h
-- Installing: /usr/include/jsoncpp/json/config.h
-- Installing: /usr/include/jsoncpp/json/forwards.h
-- Installing: /usr/include/jsoncpp/json/json.h
-- Installing: /usr/include/jsoncpp/json/json_features.h
-- Installing: /usr/include/jsoncpp/json/reader.h
-- Installing: /usr/include/jsoncpp/json/value.h
-- Installing: /usr/include/jsoncpp/json/version.h
-- Installing: /usr/include/jsoncpp/json/writer.h
配置库目录
vim ~/.bashrc
export LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH
source ~/.bashrc
三、http多线程服务
#pragma once#include <event.h>
#include <evhttp.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <iostream>
#include <thread>
#include <vector>
#include <functional>
#include <list>#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <cstdlib>
#include <jsoncpp/json/json.h>using namespace std;#define LOG_DBG printf
#define LOG_INFO printf
#define LOG_WARN printf
#define LOG_ERR printfnamespace servers
{
class HttpSrv
{
public:HttpSrv() {}~HttpSrv() {}bool start(int port, int nthreads);bool stop();protected:struct WorkRoom {HttpSrv* pSrv;struct event_base* base;struct evhttp* httpd;struct event* watchdogEv;bool dispatchStop = false;};list<WorkRoom*> workRoomList;vector<thread> mWorkThList;bool mIsExit = false;static void watchdog(int fd, short event, void* argv);void Dispatch(void* arg);static void GenericHandler(struct evhttp_request* req, void* arg);static void ProcessRequest(struct evhttp_request* request, void* arg);static void HandlePostRequest(struct evhttp_request* request, void* arg);int BindSocket(int port);
};int HttpSrv::BindSocket(int port)
{int r;int nfd;nfd = socket(AF_INET, SOCK_STREAM, 0);if (nfd < 0) return -1;int one = 1;r = setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(int));struct sockaddr_in addr;memset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET;addr.sin_addr.s_addr = INADDR_ANY;addr.sin_port = htons(port);r = bind(nfd, (struct sockaddr*)&addr, sizeof(addr));if (r < 0) return -1;r = listen(nfd, 10240);if (r < 0) return -1;int flags;if ((flags = fcntl(nfd, F_GETFL, 0)) < 0 || fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) return -1;return nfd;
}bool HttpSrv::start(int port, int nthreads) {int r;int nfd = BindSocket(port);//监听端口if (nfd < 0) return false;for (int i = 0; i < nthreads; i++){WorkRoom* w = new WorkRoom;//每个线程独有的环境参数,不使用局部变量,防止离开局部作用域后失效w->pSrv = this;w->base = event_init(); //libevnet使用多线程,每个线程中使用一个baseif (w->base == NULL) return false;w->httpd = evhttp_new(w->base);//初始化httpif (w->httpd == NULL) return false;r = evhttp_accept_socket(w->httpd, nfd);if (r != 0) return false;evhttp_set_gencb(w->httpd, GenericHandler, this); //设置http路由 404evhttp_set_cb(w->httpd, "/test", ProcessRequest, this); //设置http路由evhttp_set_cb(w->httpd, "/image", HandlePostRequest, this); //设置http路由struct timeval tv;tv.tv_sec = 1;tv.tv_usec = 0;event* watchdogEv = event_new(w->base, -1, EV_PERSIST | EV_TIMEOUT, watchdog, w);//每个base设置一个看门狗,可以做一些线程监控的工作w->watchdogEv = watchdogEv;event_add(watchdogEv, &tv);mWorkThList.push_back(std::thread(std::bind(&HttpSrv::Dispatch, this, std::placeholders::_1), w)); //启动事件分发workRoomList.push_back(w);//线程环境变量收集,善后处理}LOG_INFO("http start port:%d, thNum:%d\n", port, nthreads);return true;
}bool HttpSrv::stop() {mIsExit = true;while (workRoomList.size() > 0) {for (auto w : workRoomList) {if (!w->dispatchStop) {continue;}if (w->watchdogEv) {event_free(w->watchdogEv);w->watchdogEv = nullptr;}if (w->httpd) {evhttp_free(w->httpd);w->httpd = nullptr;}if (w->base) {event_base_free(w->base);w->base = nullptr;}workRoomList.remove(w);delete w;break;}}for (auto& t : mWorkThList) {if (t.joinable()) {t.join();}}return true;
}void HttpSrv::Dispatch(void* arg) {LOG_DBG("dispatch start\n");WorkRoom* w = (WorkRoom*)arg;event_base_dispatch(w->base);LOG_DBG("dispatch stop\n");w->dispatchStop = true;
}void HttpSrv::watchdog(int fd, short event, void* argv) {WorkRoom* w = (WorkRoom*)argv;HttpSrv* pSrv = w->pSrv;if (pSrv->mIsExit) {struct timeval delay = { 0, 1 };event_base_loopexit(w->base, &delay);}
}void HttpSrv::GenericHandler(struct evhttp_request* req, void* arg)
{((HttpSrv*)arg)->ProcessRequest(req, arg);
}void HttpSrv::ProcessRequest(struct evhttp_request* req, void* arg)
{// sleep(1);struct evbuffer* buf = evbuffer_new();if (buf == NULL)return;evbuffer_add_printf(buf, "Requested: %s\n", evhttp_request_uri(req));evhttp_send_reply(req, HTTP_OK, "OK", buf);
}void HttpSrv::HandlePostRequest(struct evhttp_request* req, void* arg)
{// Get URIconst char* uri = evhttp_request_uri(req);// Parse URIstruct evkeyvalq params;evhttp_parse_query(uri, ¶ms);// Get parametersconst char* key = evhttp_find_header(¶ms, "key");const char* key2 = evhttp_find_header(¶ms, "key2");// Check if parameters are presentif (key != NULL) {// Process key// ...return;}if (key2 != NULL) {// Process key2// ...return;}size_t len = evbuffer_get_length(req->input_buffer);char* data = (char*)malloc(len);evbuffer_remove(req->input_buffer, data, len);Json::Reader reader;Json::Value json;if (!reader.parse(data, json)) {// Handle errorreturn;}// Process JSON data// ...// Create responseJson::Value response;response["status"] = "success";Json::FastWriter writer;std::string output = writer.write(response);struct evbuffer* buf = evbuffer_new();evbuffer_add(buf, output.c_str(), output.size());evhttp_send_reply(req, HTTP_OK, "OK", buf);free(data);
}}int main()
{servers::HttpSrv s;s.start(8080, 5);sleep(60);LOG_INFO("http to stop\n");s.stop();LOG_INFO("http stop\n");}