文章目录
-
- 全流程实现博客链接
- 前引
- (二十)---- C++ High-Performance WebServer源码实现(Base核心代码部分)
-
- 1、address.h
- 2、callback.h
- 3、condition.h
- 3、condition.cc
- 4、currentthread.h
- 5、latch.h
- 6、mutex.h
- 7、noncopyable.h
- 8、timestamp.h
全流程实现博客链接
从零开始自制实现C++ High-Performance WebServer 全流程记录(基于muduo网络库)
前引
这部分写了 待会出去开开心心吃顿饭 奖励一下自己
把总结博客给发了
(二十)---- C++ High-Performance WebServer源码实现(Base核心代码部分)
1、address.h
#ifndef TINY_MUDUO_ADDRESS_H_
#define TINY_MUDUO_ADDRESS_H_#include <stdio.h>#include <string>
#include <cstring>namespace tiny_muduo {
class Address {
private:const char* ip_;const int port_;public:Address(const char* port__ = "2022") : ip_("0.0.0.0"), port_(atoi(port__)) {
}Address(const int port__ = 2022) : ip_("0.0.0.0"), port_(port__) {
}Address(const char* ip__, const char* port__) : ip_(ip__), port_(atoi(port__)) {
}Address(const char* ip__, const int port__) : ip_(ip__), port_(port__) {
}const char* ip() const {
return ip_; }int port() const {
return port_; }const std::string IpPortToString() const {
char buf[32];int len = snprintf(buf, sizeof(buf), "%s:%d", ip_, port_);return std::string(buf, buf + len);}
};}
#endif
2、callback.h
#ifndef TINY_MUDUO_CALLBACK_H_
#define TINY_MUDUO_CALLBACK_H_#include <memory>
#include <functional>using std::placeholders::_1;
using std::placeholders::_2;
using std::placeholders::_3;namespace tiny_muduo {
class TcpConnection;typedef std::shared_ptr<TcpConnection> TcpConnectionPtr;class Buffer;typedef std::function<void (const TcpConnectionPtr&, Buffer*)> ConnectionCallback;typedef std::function<void (const TcpConnectionPtr&, Buffer*)> MessageCallback;typedef std::function<void ()> ReadCallback;typedef std::function<void ()> WriteCallback;typedef std::function<void (const TcpConnectionPtr&)> CloseCallback;
}
#endif
3、condition.h
#ifndef TINY_MUDUO_CONDITION_H_
#define TINY_MUDUO_CONDITION_H_#include <pthread.h>#include "mutex.h"
#include "noncopyable.h"namespace tiny_muduo {
class Condition : public NonCopyAble {
public:explicit Condition(MutexLock& mutex) : mutex_(mutex) {
pthread_cond_init(&cond_, nullptr);}~Condition() {
pthread_cond_destroy(&cond_);}bool Wait() {
return pthread_cond_wait(&cond_, mutex_.mutex()) == 0;}bool WaitForFewSeconds(double seconds);bool Notify() {
return pthread_cond_signal(&cond_);}bool NotifyAll() {
return pthread_cond_broadcast(&cond_);}private:MutexLock& mutex_;pthread_cond_t cond_;
}; }
#endif
3、condition.cc
#include "condition.h"#include <stdint.h>
#include <sys/time.h>
#include <errno.h>using namespace tiny_muduo;bool Condition::WaitForFewSeconds(double seconds) {
struct timespec time;clock_gettime(CLOCK_MONOTONIC, &time);const int64_t kNanoSecondsPerSecond = 1000000000;int64_t nanoseconds = static_cast<int64_t>(seconds * kNanoSecondsPerSecond);time.tv_sec += static_cast<time_t>((time.tv_nsec + nanoseconds) / kNanoSecondsPerSecond);time.tv_nsec = static_cast<long>((time.tv_nsec + nanoseconds) % kNanoSecondsPerSecond);return ETIMEDOUT == pthread_cond_timedwait(&cond_, mutex_.pthreadmutex(), &time);
}
4、currentthread.h
#ifndef TINY_MUDUO_CURRENTTHREAD_H_
#define TINY_MUDUO_CURRENTTHREAD_H_#include <stdint.h>namespace CurrentThread {
extern __thread int t_cachedTid;
extern __thread char t_formattedTid[32];
extern __thread int t_formattedTidLength;void CacheTid();inline int tid() {
if (__builtin_expect(t_cachedTid == 0, 0)) {
CacheTid();}return t_cachedTid;
}inline const char* tid2string() {
return t_formattedTid; }
inline int tidstringlength() {
return t_formattedTidLength; }} // namespace CurrentThread#endif
5、latch.h
#ifndef TINY_MUDUO_LATCH_H_
#define TINY_MUDUO_LATCH_H_#include "mutex.h"
#include "condition.h"
#include "noncopyable.h"namespace tiny_muduo {
class Latch : public NonCopyAble {
public:explicit Latch(int count) : count_(count), mutex_(), cond_(mutex_) {
}void CountDown() {
MutexLockGuard lock(mutex_);--count_;if (count_ == 0) {
cond_.NotifyAll();} }void Wait() {
MutexLockGuard lock(mutex_);while (count_ > 0) {
cond_.Wait();}}private:int count_;MutexLock mutex_;Condition cond_;
};}
#endif
6、mutex.h
#ifndef TINY_MUDUO_MUTEX_H_
#define TINY_MUDUO_MUTEX_H_#include <pthread.h>#include "noncopyable.h"namespace tiny_muduo {
class MutexLock : public NonCopyAble {
public:MutexLock() {
pthread_mutex_init(&mutex_, nullptr);}~MutexLock() {
pthread_mutex_destroy(&mutex_);}pthread_mutex_t* pthreadmutex() {
return &mutex_;}bool Lock() {
return pthread_mutex_lock(&mutex_) == 0;}bool Unlock() {
return pthread_mutex_unlock(&mutex_) == 0; }pthread_mutex_t* mutex() {
return &mutex_; } private:pthread_mutex_t mutex_;
};class MutexLockGuard {
public:explicit MutexLockGuard(MutexLock& mutex) : mutex_(mutex) {
mutex_.Lock();}~MutexLockGuard() {
mutex_.Unlock();}private:MutexLock& mutex_;
};}
#endif
7、noncopyable.h
#ifndef TINY_MUDUO_NONCOPYABLE_H_
#define TINY_MUDUO_NONCOPYABLE_H_namespace tiny_muduo {
class NonCopyAble {
protected:NonCopyAble() {
}~NonCopyAble() {
}private:NonCopyAble(const NonCopyAble&) = delete;NonCopyAble& operator=(const NonCopyAble&) = delete;
};} // namespace tiny_muduo#endif
8、timestamp.h
#ifndef TINY_MUDUO_TIMESTAMP_H_
#define TINY_MUDUO_TIMESTAMP_H_#include <stdio.h>
#include <sys/time.h>#include <string>#include "noncopyable.h"const int kMicrosecond2Second = 1000 * 1000;class Timestamp {
public:Timestamp() : micro_seconds_(0) {
}explicit Timestamp(int64_t micro_seconds) : micro_seconds_(micro_seconds) {
}bool operator<(const Timestamp& rhs) const {
return micro_seconds_ < rhs.microseconds();}bool operator==(const Timestamp& rhs) const {
return micro_seconds_ == rhs.microseconds();}std::string ToFormattedDefaultLogString() const {
char buf[64] = {
0};time_t seconds = static_cast<time_t>(micro_seconds_ / kMicrosecond2Second);struct tm tm_time;localtime_r(&seconds, &tm_time);snprintf(buf, sizeof(buf), "%4d%02d%02d_%02d%02d%02d",tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec);return buf;}std::string ToFormattedString() const {
char buf[64] = {
0};time_t seconds = static_cast<time_t>(micro_seconds_ / kMicrosecond2Second);struct tm tm_time;localtime_r(&seconds, &tm_time);int micro_seconds = static_cast<int>(micro_seconds_ % kMicrosecond2Second);snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d.%06d",tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, micro_seconds);return buf;}int64_t microseconds() const {
return micro_seconds_; } static Timestamp Now();static Timestamp AddTime(const Timestamp& timestamp, double add_seconds);private:int64_t micro_seconds_;
};inline Timestamp Timestamp::Now() {
struct timeval time;gettimeofday(&time,NULL);return Timestamp(time.tv_sec * kMicrosecond2Second + time.tv_usec);
}inline Timestamp Timestamp::AddTime(const Timestamp& timestamp, double add_seconds) {
int64_t add_microseconds = static_cast<int64_t>(add_seconds) * kMicrosecond2Second; return Timestamp(timestamp.microseconds() + add_microseconds);
}#endif