C++ 多线程按顺序执行函数
我们提供了一个类:
public class Foo {
  public void first() { print("first"); }
  public void second() { print("second"); }
  public void third() { print("third"); }
}
三个不同的线程 A、B、C 将会共用一个 Foo 实例。
一个将会调用 first() 方法
一个将会调用 second() 方法
还有一个将会调用 third() 方法
请设计修改程序,以确保 second() 方法在 first() 方法之后被执行,third() 方法在 second() 方法之后被执行。
法一:信号量
#include <semaphore.h>
class Foo {
private:
    sem_t firstDone;
    sem_t secondDone;
public:
    Foo() {
        sem_init(&firstDone,0,0);
        sem_init(&secondDone,0,0);
    }
    void first(function<void()> printFirst) {
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        sem_post(&firstDone);
    }
    void second(function<void()> printSecond) {
        sem_wait(&firstDone);
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        sem_post(&secondDone);
    }
    void third(function<void()> printThird) {
        sem_wait(&secondDone);
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }
};
互斥锁:mutex
#include <semaphore.h>
class Foo {
private:
    mutex mtx1;
    mutex mtx2;
public:
    Foo() {
        mtx1.lock();
        mtx2.lock();
    }
    void first(function<void()> printFirst) {
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        mtx1.unlock();
    }
    void second(function<void()> printSecond) {
        mtx1.lock();
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        mtx1.unlock();
        mtx2.unlock();
    }
    void third(function<void()> printThird) {
        mtx2.lock();
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
        mtx2.unlock();
    }
};
RAII lock_guard, unique_lock
#include <semaphore.h>
class Foo {
private:
    mutex mtx1;
    mutex mtx2;
    unique_lock<mutex> m1lock,m2lock;
public:
    Foo() :m1lock(mtx1,try_to_lock),m2lock(mtx2,try_to_lock){
    }
    void first(function<void()> printFirst) {
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        m1lock.unlock();
    }
    void second(function<void()> printSecond) {
        lock_guard<mutex> guard(mtx1);
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        m2lock.unlock();
    }
    void third(function<void()> printThird) {
        lock_guard<mutex> guard(mtx2);
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }
};
条件变量
#include <semaphore.h>
class Foo {
private:
    condition_variable cv;
    mutex mtx;
    int k;
public:
    Foo() {
        k = 0;
    }
    void first(function<void()> printFirst) {
        printFirst();
        k = 1;
        cv.notify_all();
    }
    void second(function<void()> printSecond) {
        unique_lock<mutex> lock(mtx);
        cv.wait(lock,[this](){return k==1;});
        printSecond();
        k=2;
        cv.notify_one();
    }
    void third(function<void()> printThird) {
        unique_lock<mutex> lock(mtx);
        cv.wait(lock,[this](){return k==2;});
        printThird();
    }
};
原子操作
异步操作
class Foo {
    promise<void> pro1,pro2;
public:
    Foo() {
    }
    void first(function<void()> printFirst) {
        printFirst();
        pro1.set_value();
    }
    void second(function<void()> printSecond) {
        pro1.get_future().wait();
        printSecond();
        pro2.set_value();
    }
    void third(function<void()> printThird) {
        pro2.get_future().wait();
        printThird();
    }
};
博客地址:www.orzlinux.cn
C++ 多线程按顺序执行函数的更多相关文章
- ES6 Promise 让异步函数顺序执行
		应用 ES6 的 内置对象 Promise, 让异步函数 按顺序执行的例子 如下: 上边 是四个用Promise 处理过的 异步执行的函数: fn1.fn2.fn3.fn4 下面,让其按顺序执行 如下 ... 
- Promise 异步函数顺序执行
		可以满足需求,且使用方法和Promise.all统一 var a = function() { return new Promise(function(resolve, reject) { setTi ... 
- Qt 控制线程的顺序执行(使用QWaitCondition,并且线程类的run函数里记得加exec(),使得线程常驻)
		背景项目中用到多线程,对线程的执行顺序有要求: A.一个线程先收数据 B.一个线程处理数据 C.一个线程再将处理后的数据发送出去 要求三个线程按照ABC的顺序循环执行. 思路子类化多线程方法 重写子类 ... 
- .NET多线程执行函数
		前面几篇文章一直在写LINQ,这里为什么会出现多线程?原因是DebugLZQ在写一个LINQ综合Demo的时候遇到了多线程,便停下手来整理一下.关于多线程的文章,园子里很多很多,因此关于多线程理论性的 ... 
- js函数整合队列顺序执行插件
		前言 在日常开发中,也许我们会遇到这样的一个问题.我们利用[发布订阅模式](如果不了解的可以直接访问此链接www.cnblogs.com/xiaoxiaokun- )去执行[发布]事件时,遇到函数内部 ... 
- 更优雅的方式: JavaScript 中顺序执行异步函数
		火于异步 1995年,当时最流行的浏览器--网景中开始运行 JavaScript (最初称为 LiveScript). 1996年,微软发布了 JScript 兼容 JavaScript.随着网景.微 ... 
- UI基础:UI程序执行顺序(UIApplicationMain()函数),自定义视图                                                    分类:            iOS学习-UI             2015-07-02 22:09    68人阅读    评论(0)    收藏
		UI程序的一般执行顺序: 先进入main里面,执行函数UIApplicationMain(),通过该函数创建应用程序对象和指定其代理并实现监听,当执行函数UIApplicationMain()时还会做 ... 
- C# 不使用Task实现的多线程顺序执行
		多线程有很好的并发性即无序性,在某些特殊情况下需要用到多线程然而又要使其具备顺序性,这种时候就有了一个特殊的场景那就是多线程顺序执行,在现在VS2015中Task自带了顺序执行的方法,但在此之前的旧项 ... 
- [Thread] 多线程顺序执行
		Join 主线程join 启动线程t1,随后调用join,main线程需要等t1线程执行完毕后继续执行. public class MainJoin { static class MyThread i ... 
随机推荐
- Float浮动(慕课网学习笔记)
			float浮动 属性:值 意义 float:left 左浮动 float:right 右浮动 float:none 不浮动 float:inherit 继承父元素浮动属性,若父元素没有浮动属性则失效 ... 
- BeanUtils实现对象拷贝(三)
			package beanutil; import java.lang.reflect.InvocationTargetException; import java.util.Date; import ... 
- Spring系列之集成Druid连接池及监控配置
			前言 前一篇文章我们熟悉了HikariCP连接池,也了解到它的性能很高,今天我们讲一下另一款比较受欢迎的连接池:Druid,这是阿里开源的一款数据库连接池,它官网上声称:为监控而生!他可以实现页面监控 ... 
- springcloud<zuul过滤器简单配置与跨域设置>
			package com.wangbiao.config; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.Req ... 
- mongodb重启报错解决
			mongodb关闭后重启失败 connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName= ... 
- Windows-MacOSX-Ubuntu·不同平台文件互传文件共享
			时间:2018-11-23 整理:byzqy 标题:Mac下的virtual box 安装的Ubuntu虚拟机互传文件问题 地址:https://blog.csdn.net/qq_20044689/a ... 
- WEB漏洞——XSS
			跨站脚本( Cross-site Scripting,简称为XSS或跨站脚本或跨站脚本攻击)是一种针对网站应用程序的安全漏洞攻击技术,是代码注入的一种. XSS攻击可以分为三种:反射型.存储型和DOM ... 
- POJ2251——Dungeon Master(三维BFS)
			和迷宫问题区别不大,相比于POJ1321的棋盘问题,这里的BFS是三维的,即从4个方向变为6个方向. 用上队列的进出操作较为轻松. #include<iostream> #include& ... 
- 数据结构逆向分析-Map
			数据结构逆向分析-Map map是一个典型的二叉树结构,准确的来说是一个平衡二叉树或者红黑树,特点是数据存储是有序的存储. 参考侯杰老师的stl源码剖析,map里面采用的是RB-TREE也就是红黑树 ... 
- 在FLASH中读写结构体
			在FLASH中读写结构体 注意事项 编程(写数据)地址要对齐 写数据时,我们要指定写入的地址,如果写入地址为非对齐,则会出现编程对齐错误. 比如遵循32位(4字节)地址对齐,你的地址只能是4的倍数.0 ... 
