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

丹江口网站制作图片制作视频的app

丹江口网站制作,图片制作视频的app,如何在阿里云上建设网站,网络营销策划书怎么写1. 巴基的订单 在海贼世界中#xff0c;巴基速递是巴基依靠手下强大的越狱犯兵力#xff0c;组建的集团海贼派遣公司#xff0c;它的主要业务是向世界有需要的地方输送雇佣兵#xff08;其实是不干好事儿#xff09;。 自从从特拉法尔加罗和路飞同盟击败了堂吉诃德家族 巴基速递是巴基依靠手下强大的越狱犯兵力组建的集团海贼派遣公司它的主要业务是向世界有需要的地方输送雇佣兵其实是不干好事儿。 自从从特拉法尔加罗和路飞同盟击败了堂吉诃德家族 战争的市场对雇佣兵的依赖越来越大。订单便源源不断的来了。此时我们来分析一个问题巴基是怎么接单并且派单的呢 简单来说巴基肯定是有一个账本用于记录下单者信息下单者的需求以及下单的时间然后根据下单的先后顺序选择合适的人手进行派单。从程序猿的视角可以这样认为这个账本其实就相当于一个任务队列 有一定的容量可以存储任务按照下单的先后顺序存储并处理任务 – 典型的队列特性先进先出 对于巴基来说把所有的订单全部记录到一个账本上就够了如果将其平移到项目中也就意味着应用程序在运行过程中存储任务的任务队列一个足矣弄太多反而冗余不太好处理了。 在一个项目中全局范围内某个类的实例有且仅有一个通过这个唯一实例向其他模块提供数据的全局访问这种模式就叫单例模式。单例模式的典型应用就是任务队列。 2. 独生子女 如果使用单例模式首先要保证这个类的实例有且仅有一个也就是说这个对象是独生子女如果我们实施计划生育只生一个孩子不需要也不能给再他增加兄弟姐妹。因此就必须采取一系列的防护措施。对于类来说以上描述同样适用。涉及一个类多对象操作的函数有以下几个 构造函数创建一个新的对象拷贝构造函数根据已有对象拷贝出一个新的对象拷贝赋值操作符重载函数两个对象之间的赋值 为了把一个类可以实例化多个对象的路堵死可以做如下处理 构造函数私有化在类内部只调用一次这个是可控的。 由于使用者在类外部不能使用构造函数所以在类内部创建的这个唯一的对象必须是静态的这样就可以通过类名来访问了为了不破坏类的封装我们都会把这个静态对象的访问权限设置为私有的。在类中只有它的静态成员函数才能访问其静态成员变量所以可以给这个单例类提供一个静态函数用于得到这个静态的单例对象。 拷贝构造函数私有化或者禁用使用 delete 拷贝赋值操作符重载函数私有化或者禁用从单例的语义上讲这个函数已经毫无意义所以在类中不再提供这样一个函数故将它也一并处理一下。 由于单例模式就是给类创建一个唯一的实例对象所以它的UML类图是很简单的 因此定义一个单例模式的类的示例代码如下 // 定义一个单例模式的类 class Singleton { public:// delete 代表函数禁用, 也可以将其访问权限设置为私有Singleton(const Singleton obj) delete;Singleton operator(const Singleton obj) delete;static Singleton* getInstance(); private:Singleton() default;static Singleton* m_obj; };在实现一个单例模式的类的时候有两种处理模式 饿汉模式懒汉模式 3. 饿汉模式 饿汉模式就是在类加载的时候立刻进行实例化这样就得到了一个唯一的可用对象。关于这个饿汉模式的类的定义如下: // 饿汉模式 class TaskQueue { public:// delete 代表函数禁用, 也可以将其访问权限设置为私有TaskQueue(const TaskQueue obj) delete;TaskQueue operator(const TaskQueue obj) delete;static TaskQueue* getInstance(){return m_taskQ;} private:TaskQueue() default;static TaskQueue* m_taskQ; }; // 静态成员初始化放到类外部处理 TaskQueue* TaskQueue::m_taskQ new TaskQueue;int main() {TaskQueue* obj TaskQueue::getInstance(); }在第17行定义这个单例类的时候就把这个静态的单例对象创建出来了。当使用者通过getInstance()获取这个单例对象的时候它已经被准备好了。 注意事项类的静态成员变量在使用之前必须在类的外部进行初始化才能使用。 4. 懒汉模式 懒汉模式是在类加载的时候不去创建这个唯一的实例而是在需要使用的时候再进行实例化。 4.1 懒汉模式类的定义 // 懒汉模式 class TaskQueue { public:// delete 代表函数禁用, 也可以将其访问权限设置为私有TaskQueue(const TaskQueue obj) delete;TaskQueue operator(const TaskQueue obj) delete;static TaskQueue* getInstance(){if(m_taskQ nullptr){m_taskQ new TaskQueue;}return m_taskQ;} private:TaskQueue() default;static TaskQueue* m_taskQ; }; TaskQueue* TaskQueue::m_taskQ nullptr;在调用getInstance()函数获取单例对象的时候如果在单线程情况下是没有什么问题的如果是多个线程调用这个函数去访问单例对象就有问题了。假设有三个线程同时执行了getInstance()函数在这个函数内部每个线程都会new出一个实例对象。此时这个任务队列类的实例对象不是一个而是3个很显然这与单例模式的定义是相悖的。 4.2 线程安全问题 双重检查锁定 对于饿汉模式是没有线程安全问题的在这种模式下访问单例对象的时候这个对象已经被创建出来了。要解决懒汉模式的线程安全问题最常用的解决方案就是使用互斥锁。可以将创建单例对象的代码使用互斥锁锁住处理代码如下 class TaskQueue { public:// delete 代表函数禁用, 也可以将其访问权限设置为私有TaskQueue(const TaskQueue obj) delete;TaskQueue operator(const TaskQueue obj) delete;static TaskQueue* getInstance(){m_mutex.lock();if (m_taskQ nullptr){m_taskQ new TaskQueue;}m_mutex.unlock();return m_taskQ;} private:TaskQueue() default;static TaskQueue* m_taskQ;static mutex m_mutex; }; TaskQueue* TaskQueue::m_taskQ nullptr; mutex TaskQueue::m_mutex;在上面代码的10~13 行这个代码块被互斥锁锁住了也就意味着不论有多少个线程同时执行这个代码块的线程只能是一个相当于是严重限行了在重负载情况下可能导致响应缓慢。我们可以将代码再优化一下 class TaskQueue { public:// delete 代表函数禁用, 也可以将其访问权限设置为私有TaskQueue(const TaskQueue obj) delete;TaskQueue operator(const TaskQueue obj) delete;static TaskQueue* getInstance(){if (m_taskQ nullptr){m_mutex.lock();if (m_taskQ nullptr){m_taskQ new TaskQueue;}m_mutex.unlock();}return m_taskQ;} private:TaskQueue() default;static TaskQueue* m_taskQ;static mutex m_mutex; }; TaskQueue* TaskQueue::m_taskQ nullptr; mutex TaskQueue::m_mutex;改进的思路就是在加锁、解锁的代码块外层有添加了一个if判断第9行这样当任务队列的实例被创建出来之后访问这个对象的线程就不会再执行加锁和解锁操作了只要有了单例类的实例对象限行就解除了对于第一次创建单例对象的时候线程之间还是具有竞争关系被互斥锁阻塞。上面这种通过两个嵌套的 if 来判断单例对象是否为空的操作就叫做双重检查锁定。 双重检查锁定的问题 假设有两个线程A、B当线程A 执行到第 8 行时在线程A中 TaskQueue 实例对象 被创建并赋值给 m_taskQ。 static TaskQueue* getInstance() {if (m_taskQ nullptr){m_mutex.lock();if (m_taskQ nullptr){m_taskQ new TaskQueue;}m_mutex.unlock();}return m_taskQ; }但是实际上 m_taskQ new TaskQueue; 在执行过程中对应的机器指令可能会被重新排序。正常过程如下 第一步分配内存用于保存 TaskQueue 对象。第二步在分配的内存中构造一个 TaskQueue 对象初始化内存。第三步使用 m_taskQ 指针指向分配的内存。 但是被重新排序以后执行顺序可能会变成这样 第一步分配内存用于保存 TaskQueue 对象。第二步使用 m_taskQ 指针指向分配的内存。第三步在分配的内存中构造一个 TaskQueue 对象初始化内存。 这样重排序并不影响单线程的执行结果但是在多线程中就会出问题。如果线程A按照第二种顺序执行机器指令执行完前两步之后失去CPU时间片被挂起了此时线程B在第3行处进行指针判断的时候m_taskQ 指针是不为空的但这个指针指向的内存却没有被初始化最后线程 B 使用了一个没有被初始化的队列对象就出问题了出现这种情况是概率问题需要反复的大量测试问题才可能会出现。 在C11中引入了原子变量atomic通过原子变量可以实现一种更安全的懒汉模式的单例代码如下 class TaskQueue { public:// delete 代表函数禁用, 也可以将其访问权限设置为私有TaskQueue(const TaskQueue obj) delete;TaskQueue operator(const TaskQueue obj) delete;static TaskQueue* getInstance(){TaskQueue* queue m_taskQ.load(); if (queue nullptr){// m_mutex.lock(); // 加锁: 方式1lock_guardmutex locker(m_mutex); // 加锁: 方式2queue m_taskQ.load();if (queue nullptr){queue new TaskQueue;m_taskQ.store(queue);}// m_mutex.unlock();}return queue;}void print(){cout hello, world!!! endl;} private:TaskQueue() default;static atomicTaskQueue* m_taskQ;static mutex m_mutex; }; atomicTaskQueue* TaskQueue::m_taskQ; mutex TaskQueue::m_mutex;int main() {TaskQueue* queue TaskQueue::getInstance();queue-print();return 0; }上面代码中使用原子变量atomic的store() 方法来存储单例对象使用load() 方法来加载单例对象。在原子变量中这两个函数在处理指令的时候默认的原子顺序是memory_order_seq_cst顺序原子操作 - sequentially consistent使用顺序约束原子操作库整个函数执行都将保证顺序执行并且不会出现数据竞态data races不足之处就是使用这种方法实现的懒汉模式的单例执行效率更低一些。 静态局部对象 在实现懒汉模式的单例的时候相较于双重检查锁定模式有一种更简单的实现方法并且不会出现线程安全问题那就是使用静态局部局部对象对应的代码实现如下 class TaskQueue { public:// delete 代表函数禁用, 也可以将其访问权限设置为私有TaskQueue(const TaskQueue obj) delete;TaskQueue operator(const TaskQueue obj) delete;static TaskQueue* getInstance(){static TaskQueue taskQ;return taskQ;}void print(){cout hello, world!!! endl;}private:TaskQueue() default; };int main() {TaskQueue* queue TaskQueue::getInstance();queue-print();return 0; }在程序的第 9、10 行定义了一个静态局部队列对象并且将这个对象作为了唯一的单例实例。使用这种方式之所以是线程安全的是因为在C11标准中有如下规定并且这个操作是在编译时由编译器保证的 如果指令逻辑进入一个未被初始化的声明变量所有并发执行应当等待该变量完成初始化。 最后总结一下懒汉模式和饿汉模式的区别 懒汉模式的缺点是在创建实例对象的时候有安全问题但这样可以减少内存的浪费如果用不到就不去申请内存了。饿汉模式则相反在我们不需要这个实例对象的时候它已经被创建出来占用了一块内存。对于现在的计算机而言内存容量都是足够大的这个缺陷可以被无视。 5. 替巴基写一个任务队列 作为程序猿的我们如果想给巴基的账本升级成一个应用程序首要任务就是设计一个单例模式的任务队列那么就需要赋予这个类一些属性和方法 属性 存储任务的容器这个容器可以选择使用STL中的队列queue)互斥锁多线程访问的时候用于保护任务队列中的数据 方法主要是对任务队列中的任务进行操作 任务队列中任务是否为空往任务队列中添加一个任务从任务队列中取出一个任务从任务队列中删除一个任务 根据分析就可以把这个饿汉模式的任务队列的单例类定义出来了 #include iostream #include queue #include mutex #include thread using namespace std;class TaskQueue { public:// delete 代表函数禁用, 也可以将其访问权限设置为私有TaskQueue(const TaskQueue obj) delete;TaskQueue operator(const TaskQueue obj) delete;static TaskQueue* getInstance(){return m_obj;}// 任务队列是否为空bool isEmpty(){lock_guardmutex locker(m_mutex);bool flag m_taskQ.empty();return flag;}// 添加任务void addTask(int data){lock_guardmutex locker(m_mutex);m_taskQ.push(data);}// 取出一个任务int takeTask(){lock_guardmutex locker(m_mutex);if (!m_taskQ.empty()){return m_taskQ.front();}return -1;}// 删除一个任务bool popTask(){lock_guardmutex locker(m_mutex);if (!m_taskQ.empty()){m_taskQ.pop();return true;}return false;} private:TaskQueue() default;static TaskQueue m_obj;queueint m_taskQ;mutex m_mutex; }; TaskQueue TaskQueue::m_obj;int main() {thread t1([]() {TaskQueue* taskQ TaskQueue::getInstance();for (int i 0; i 100; i){taskQ-addTask(i 100);cout push task: i 100 , threadID: this_thread::get_id() endl;this_thread::sleep_for(chrono::milliseconds(500));}});thread t2([]() {TaskQueue* taskQ TaskQueue::getInstance();this_thread::sleep_for(chrono::milliseconds(100));while (!taskQ-isEmpty()){int data taskQ-takeTask();cout ---take task: data , threadID: this_thread::get_id() endl;taskQ-popTask();this_thread::sleep_for(chrono::seconds(1));}});t1.join();t2.join(); }在上面的程序中有以下几点需要说明一下 正常情况下任务队列中的任务应该是一个函数指针这个指针指向的函数中有需要执行的任务动作此处进行了简化用一个整形数代替了任务队列中的任务。任务队列中的互斥锁保护的是单例对象的中的数据也就是任务队列中的数据上面所说的线程安全指的是在创建单例对象的时候要保证这个对象只被创建一次和此处完全是两码事儿需要区别看待。
http://www.hkea.cn/news/14362218/

相关文章:

  • 详细描述建设一个网站的具体步骤所谓网页制作三剑客不包括
  • 国内永久免费域名申请网站php做网站视频
  • 做网站从何开始公司注册资金实缴新政策出台2024
  • 百度基木鱼建站郑州最好的男科医院是什么医院
  • 郑州建站推广公司求一个做美食视频的网站
  • 绍兴网站建设哪家专业建立网站目录的时候
  • 爱站网注册人查询模板网站怎么做才美观
  • 城乡和住房建设部网站营销宣传方式有哪些
  • 上海做网站开发的公司有哪些哈尔滨信息网招聘
  • 泰安网站建设找工作网站建设挣钱吗
  • 网站开发联系方式北海市网站建设
  • 污网站公司网站中山网站免费制作
  • 自适应网站的图做多大 怎么切莱芜信息平台
  • 广州网站模板建站公司网站开发费用入什么科目
  • 网络科技公司门户网站建筑人才评价网
  • 网站开发合同 doc免费模板
  • 网站分几类wordpress 漏洞检测
  • 做一个展示型网站多少钱软件公司找项目
  • 网上有兼职做数据网站深圳公司注册地址要求
  • 工会网站建设企业网站seo参考文献
  • 国外做的比较好看的网站企业网上年审营业执照
  • 大腕 网站建设网页动效 wordpress
  • dedecms模板站外包制作app
  • 金融网站开发抖音代运营有效果吗
  • 二级学院网站建设自评报告西安网络推广网站优化
  • 南通网站建设企业wordpress二级菜单添加链接
  • 怎么做徐州市环保局网站备案表深圳龙江网站设计
  • 政务公开和网站建设工作问题简单网站制作代码
  • 网站推广做的比较好的公司wordpress 页面代码
  • 台州做网站建设wordpress源码解读