当前位置: 首页 > news >正文

中国十大网站建设公司wordpress ftp 端口

中国十大网站建设公司,wordpress ftp 端口,wordpress zip 升级,seo关键词的优化技巧目录 封装条件变量 POSIX信号量 初始化信号量 销毁信号量 等待信号量 发布信号量 封装信号量 基于环形队列的⽣产消费模型 日志 封装 封装条件变量 比较简单,不做讲解。 namespace CondModule {class Cond{public:Cond(){pthread_cond_init(&_cond,…

目录

封装条件变量

POSIX信号量

初始化信号量

销毁信号量

等待信号量

发布信号量

封装信号量

基于环形队列的⽣产消费模型

日志

封装


封装条件变量

比较简单,不做讲解。

namespace CondModule
{class Cond{public:Cond(){pthread_cond_init(&_cond,nullptr);}void Wait(Mutex& mutex){pthread_cond_wait(&_cond,mutex.Get());}void Singal(){pthread_cond_signal(&_cond);}void Broadcast(){pthread_cond_broadcast(&_cond);}~Cond(){pthread_cond_destroy(&_cond);}private:pthread_cond_t _cond;};
}

至此,我们封装了互斥锁,线程和条件变量,所以我们可以用我们自己的轮子来写前面的阻塞队列。

using namespace MutexModule;
using namespace CondModule;const int defaultcap = 5;
template <typename T>
class BlockQueue
{bool IsFull() { return _q.size() >= _cal; }bool IsEmpty() { return _q.empty(); }public:BlockQueue(int cal = defaultcap): _cal(cal),_psleep_num(0),_csleep_num(0){}void Enqueue(const T &in){// pthread_mutex_lock(&_mutex); //上锁LockGuard lockguard(_mutex);//上锁// 生产者调用while (IsFull()){_psleep_num++;// pthread_cond_wait(&_full_cond, &_mutex);//等待_full_cond.Wait(_mutex);//等待_psleep_num--;}_q.push(in);if (_csleep_num > 0)// pthread_cond_signal(&_empty_cond);//唤醒_empty_cond.Singal();}T Pop(){// 消费者调用// pthread_mutex_lock(&_mutex);//上锁LockGuard lockguard(_mutex);//上锁while (IsEmpty()){_csleep_num++;// pthread_cond_wait(&_empty_cond, &_mutex);//等待_empty_cond.Wait(_mutex);_csleep_num--;}T data = _q.front();_q.pop();if (_psleep_num > 0)// pthread_cond_signal(&_full_cond);//唤醒_full_cond.Singal();//唤醒return data;}~BlockQueue(){}
private:std::queue<T> _q;int _cal; // 大小Mutex _mutex;Cond _full_cond;Cond _empty_cond;int _csleep_num; // 消费者休眠的个数int _psleep_num; // 生产者休眠的个数
};

POSIX信号量

POSIX信号量和SystemV信号量作⽤相同,都是⽤于同步操作,达到⽆冲突的访问共享资源⽬的。但 POSIX可以⽤于线程间同步。

初始化信号量

销毁信号量

等待信号量

发布信号量

封装信号量

namespace SemModule
{const int defaultvaule=1;class Sem{public:Sem(unsigned int value=defaultvaule){sem_init(&_sem,0,value);}void P(){sem_wait(&_sem);//-- 申请信号量 原子的}void V(){sem_post(&_sem);//++ 释放信号量 原子的}~Sem(){sem_destroy(&_sem);}private:sem_t _sem;};
}

基于环形队列的⽣产消费模型

  •  形队列采⽤数组模拟,⽤模运算来模拟环状特性
  • 环形结构起始状态和结束状态都是⼀样的,不好判断为空或者为满,所以可以通过加计数器或者 标记位来判断满或者空。另外也可以预留⼀个空的位置,作为满的状态

理解:

1.当队列为空,生产者先运行。

2.当队列为满,消费者先运行。

3.消费者不得超过生产者。

4.当生产者和消费者在同一个位置时,只能为空或为满,也就是说只要不为空和满,消费者和生产者就能同时进行(并发)。

我们先看单生产单消费:

代码:

const int defaultcap = 5;
using namespace SemModule;
template <class T>
class RingQueue
{
public:RingQueue(int cap = defaultcap): _cap(cap), _rq(cap), _blank_sem(cap), _data_sem(0),_p_step(0), _c_step(0){}void Equeue(const T &in){// 生产者调用_blank_sem.P();      // 申请空位置信号量_rq[_p_step++] = in; // 生产_p_step %= _cap;     // 维持环状_data_sem.V();       // 数据信号量要++}void Pop(T *out) // 输出型参数{// 消费者调用_data_sem.P();         // 申请数据信号量*out = _rq[_c_step++]; // 将数据带出去消费_c_step %= _cap;       // 维持环状_blank_sem.V();        // 空位置信号量要++}
private:std::vector<T> _rq;int _cap; // 大小// 生产者Sem _blank_sem; // 空位置信号量int _p_step;// 消费者Sem _data_sem; // 数据信号量int _c_step;
};

我们来看多生产,多消费:

多生产多消费,我们需要用锁。

不管是生产还是消费,任意时刻都是单个线程生产或消费,所以我们要用锁。

1.

问题:生产者或消费者是先申请信号量还是先加锁?

先申请信号量再加锁,这样快!

因为:我们可以先将资源全部申请出去,然后一个一个生产或消费。

如果是先加锁再申请信号量,这样就会将资源一个一个申请然后消费!显然,第一种快!

2.

我们写好了单生产单消费,就已经维持了消费者和生产者的互斥和同步,要写多生产多消费其实就是要维持消费者和消费者之间,生产者和生产者之间的同步与互斥关系!需要俩把锁。

3.

多线程使用资源,有俩种场景:

将资源整体使用,应用mutex+2元信号量(也就是条件变量),将资源按照不同块,分批使用,应用信号量。

代码:

const int defaultcap = 5;
using namespace SemModule;
using namespace MutexModule;
template <class T>
class RingQueue
{
public:RingQueue(int cap = defaultcap): _cap(cap), _rq(cap), _blank_sem(cap), _data_sem(0),_p_step(0), _c_step(0){}void Equeue(const T &in){// 生产者调用_blank_sem.P(); // 申请空位置信号量{LockGuard lockguard(_pmutex);_rq[_p_step++] = in; // 生产_p_step %= _cap;     // 维持环状}_data_sem.V(); // 数据信号量要++}void Pop(T *out) // 输出型参数{// 消费者调用_data_sem.P(); // 申请数据信号量{LockGuard lockguard(_cmutex);*out = _rq[_c_step++]; // 将数据带出去消费_c_step %= _cap;       // 维持环状}_blank_sem.V(); // 空位置信号量要++}private:std::vector<T> _rq;int _cap; // 大小Mutex _cmutex;//消费者锁Mutex _pmutex;//生产者锁// 生产者Sem _blank_sem; // 空位置信号量int _p_step;// 消费者Sem _data_sem; // 数据信号量int _c_step;
};

日志

⽇志认识

计算机中的⽇志是记录系统和软件运⾏中发⽣事件的⽂件,主要作⽤是监控运⾏状态、记录异常信 息,帮助快速定位问题并⽀持程序员进⾏问题修复。它是系统维护、故障排查和安全管理的重要⼯ 具。

⽇志格式以下⼏个指标是必须得有的:

  • 时间戳
  • ⽇志等级
  • ⽇志内容

以下⼏个指标是可选的:

  • ⽂件名⾏号
  • 进程,线程相关id信息等

⽇志有现成的解决⽅案,如:spdlog、glog、Boost.Log、Log4cxx等等,我们依旧采⽤⾃定义⽇志的 ⽅式。

我们想要的⽇志格式如下:

封装

刷新策略

日志:

我们采用内部类方法实现:

外部类可以直接通过内部类的对象访问其成员(因为内部类的定义在外部类作用域内可见)。

内部类使用外部类成员需要对象或者指针。

最后我们可以使用宏来简化调用:

代码:

namespace LogModule
{using namespace MutexModule;const std::string gsep = "\r\n";// 刷新策略基类class LogStrategy{public:~LogStrategy() = default;virtual void SyncLog(const std::string &message) = 0;};// 显示器打印:子类class ConsoleLogStrategy : public LogStrategy{public:void SyncLog(const std::string &message) override{LockGuard lockguard(_mutex);std::cout << message << gsep;}private:Mutex _mutex;};const std::string defaultpath = "./log";const std::string defaultfile = "my.log";// 文件打印:子类class FileLogStrategy : public LogStrategy{public:FileLogStrategy(const std::string &path = defaultpath,const std::string &file = defaultfile): _path(path), _file(file){LockGuard lockguard(_mutex);if (std::filesystem::exists(_path))return;try{std::filesystem::create_directories(_path);}catch (const std::filesystem::filesystem_error &e){std::cerr << e.what() << '\n';}}void SyncLog(const std::string &message) override{LockGuard lockguard(_mutex);std::string filename = _path + (_path.back() == '/' ? "" : "/") + _file;std::ofstream out(filename, std::ios::app); // 追加方式写入if (!out.is_open())return;out << message << gsep;out.close();}private:std::string _path;std::string _file;Mutex _mutex;};// 日志等级enum class LogLevel{DEBUG,INFO,WARNING,ERROR,FATAL};// 将日志等级转化成stringstd::string LevelToStr(LogLevel level){switch (level){case LogLevel::DEBUG:return "DEBUG";case LogLevel::ERROR:return "ERROR";case LogLevel::FATAL:return "FATAL";case LogLevel::INFO:return "INFO";case LogLevel::WARNING:return "WARNING";default:return "UNKNOWN";}}// 获得当前时间std::string GetTimeStamp(){time_t curr = time(nullptr);struct tm curr_tm;localtime_r(&curr, &curr_tm);char timebuffer[128];snprintf(timebuffer, sizeof(timebuffer), "%4d-%02d-%02d %02d:%02d:%02d",curr_tm.tm_year + 1900,curr_tm.tm_mon + 1,curr_tm.tm_mday,curr_tm.tm_hour,curr_tm.tm_min,curr_tm.tm_sec);return timebuffer;}//日志类class Logger{public:Logger(){EnableConsoleStrategy();}void EnableConsoleStrategy(){_fflush_strategy = std::make_unique<ConsoleLogStrategy>();}void EnableFileStrategy(){_fflush_strategy = std::make_unique<FileLogStrategy>();}// 将来是一条日志class LogMessage{public:LogMessage(LogLevel &level, std::string &src_name,int line_number, Logger &logger): _curr_time(GetTimeStamp()), _level(level),_src_name(src_name), _line_number(line_number),_logger(logger), _pid(getpid()){std::stringstream ss;ss << "[" << _curr_time << "]"<< "[" << LevelToStr(_level) << "]"<< "[" << _pid << "]"<< "[" << _src_name << "]"<< "[" << _line_number << "]"<< "- ";_loginfo = ss.str();}// LogMessage()<<"  "<<11template <class T>LogMessage &operator<<(const T &info){std::stringstream ss;ss << info;_loginfo += ss.str();return *this;}~LogMessage(){if (_logger._fflush_strategy){_logger._fflush_strategy->SyncLog(_loginfo);}}private:std::string _curr_time;LogLevel _level;pid_t _pid;std::string _src_name;int _line_number;std::string _loginfo; // 一条日志合并的完整信息Logger &_logger;};// 重载()LogMessage operator()(LogLevel level, std::string name, int line){return LogMessage(level, name, line, *this);}private:std::unique_ptr<LogStrategy> _fflush_strategy;};// 全局Logger logger;
// 使用宏,简化用户操作,获取文件名和行号
#define LOG(level) logger(level, __FILE__, __LINE__)
#define Enable_Console_Log_Strategy() logger.EnableConsoleStrategy()
#define Enable_File_Log_Strategy() logger.EnableFileLogStrategy()
}

我们下期见。

http://www.dtcms.com/a/523452.html

相关文章:

  • 长沙商城网站建设报价公示网站制作联盟
  • saas网站建设网站常见程序问题
  • 网站建设视频上传珠海市城乡住房建设局网站
  • 西安 房产网站建设拍卖网站建设方案
  • 做网站的一般步骤wordpress oss upload
  • 佛山网站制作对网页设计的认识和理解
  • 响水做网站哪家最好电子商务平台官网
  • 建什么网站容易挣钱wordpress会员空间插件
  • 微网站开发平台 知乎河南网站排名优化哪家好
  • 网站开发策划书怎么写西宁整站优化
  • 网站首页介绍苏州做公司网站设计的公司
  • wordpress 图片 视频外贸网站怎么做seo优化
  • 大连本站运营公司wordpress建什么网站好
  • 网站备案工信部购物网站策划建设方案
  • 外贸网站域名企业标识设计
  • 四川建设厅网站徐州网站建设方案维护
  • 微信链接的微网站怎么做个人备案网站做购物网站可以不
  • 智能网站建设策划微信app下载安装官方版2023
  • 哪些网站可以seo温州微网站开发
  • 建设网站公司电话销售话术移动互联网包含( )三个方面
  • 私人承接做网站多少钱wordpress 源码分析
  • 优秀网站建设空间网络科技公司注册资金多少
  • 网站建设项目实训报告西安seo关键词排名优化
  • 九江市住房和城乡建设局官方网站seo排名怎么做
  • 中山网站建设乐云seo模板中心郑州网站个人开发
  • c语言网站做网站程序的步骤
  • 凡科建站是永久的吗wordpress地产主题
  • 环保空调东莞网站建设中国重大新闻
  • 衡水武邑县建设局网站重庆网站建设川娃子
  • dw怎么做网站企业管理咨询有限公司经营范围