我们提供了一个类:

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++ 多线程按顺序执行函数的更多相关文章

  1. ES6 Promise 让异步函数顺序执行

    应用 ES6 的 内置对象 Promise, 让异步函数 按顺序执行的例子 如下: 上边 是四个用Promise 处理过的 异步执行的函数: fn1.fn2.fn3.fn4 下面,让其按顺序执行 如下 ...

  2. Promise 异步函数顺序执行

    可以满足需求,且使用方法和Promise.all统一 var a = function() { return new Promise(function(resolve, reject) { setTi ...

  3. Qt 控制线程的顺序执行(使用QWaitCondition,并且线程类的run函数里记得加exec(),使得线程常驻)

    背景项目中用到多线程,对线程的执行顺序有要求: A.一个线程先收数据 B.一个线程处理数据 C.一个线程再将处理后的数据发送出去 要求三个线程按照ABC的顺序循环执行. 思路子类化多线程方法 重写子类 ...

  4. .NET多线程执行函数

    前面几篇文章一直在写LINQ,这里为什么会出现多线程?原因是DebugLZQ在写一个LINQ综合Demo的时候遇到了多线程,便停下手来整理一下.关于多线程的文章,园子里很多很多,因此关于多线程理论性的 ...

  5. js函数整合队列顺序执行插件

    前言 在日常开发中,也许我们会遇到这样的一个问题.我们利用[发布订阅模式](如果不了解的可以直接访问此链接www.cnblogs.com/xiaoxiaokun- )去执行[发布]事件时,遇到函数内部 ...

  6. 更优雅的方式: JavaScript 中顺序执行异步函数

    火于异步 1995年,当时最流行的浏览器--网景中开始运行 JavaScript (最初称为 LiveScript). 1996年,微软发布了 JScript 兼容 JavaScript.随着网景.微 ...

  7. UI基础:UI程序执行顺序(UIApplicationMain()函数),自定义视图 分类: iOS学习-UI 2015-07-02 22:09 68人阅读 评论(0) 收藏

    UI程序的一般执行顺序: 先进入main里面,执行函数UIApplicationMain(),通过该函数创建应用程序对象和指定其代理并实现监听,当执行函数UIApplicationMain()时还会做 ...

  8. C# 不使用Task实现的多线程顺序执行

    多线程有很好的并发性即无序性,在某些特殊情况下需要用到多线程然而又要使其具备顺序性,这种时候就有了一个特殊的场景那就是多线程顺序执行,在现在VS2015中Task自带了顺序执行的方法,但在此之前的旧项 ...

  9. [Thread] 多线程顺序执行

    Join 主线程join 启动线程t1,随后调用join,main线程需要等t1线程执行完毕后继续执行. public class MainJoin { static class MyThread i ...

随机推荐

  1. Float浮动(慕课网学习笔记)

    float浮动 属性:值 意义 float:left 左浮动 float:right 右浮动 float:none 不浮动 float:inherit 继承父元素浮动属性,若父元素没有浮动属性则失效 ...

  2. BeanUtils实现对象拷贝(三)

    package beanutil; import java.lang.reflect.InvocationTargetException; import java.util.Date; import ...

  3. Spring系列之集成Druid连接池及监控配置

    前言 前一篇文章我们熟悉了HikariCP连接池,也了解到它的性能很高,今天我们讲一下另一款比较受欢迎的连接池:Druid,这是阿里开源的一款数据库连接池,它官网上声称:为监控而生!他可以实现页面监控 ...

  4. springcloud<zuul过滤器简单配置与跨域设置>

    package com.wangbiao.config; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.Req ...

  5. mongodb重启报错解决

    mongodb关闭后重启失败 connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName= ...

  6. Windows-MacOSX-Ubuntu·不同平台文件互传文件共享

    时间:2018-11-23 整理:byzqy 标题:Mac下的virtual box 安装的Ubuntu虚拟机互传文件问题 地址:https://blog.csdn.net/qq_20044689/a ...

  7. WEB漏洞——XSS

    跨站脚本( Cross-site Scripting,简称为XSS或跨站脚本或跨站脚本攻击)是一种针对网站应用程序的安全漏洞攻击技术,是代码注入的一种. XSS攻击可以分为三种:反射型.存储型和DOM ...

  8. POJ2251——Dungeon Master(三维BFS)

    和迷宫问题区别不大,相比于POJ1321的棋盘问题,这里的BFS是三维的,即从4个方向变为6个方向. 用上队列的进出操作较为轻松. #include<iostream> #include& ...

  9. 数据结构逆向分析-Map

    数据结构逆向分析-Map map是一个典型的二叉树结构,准确的来说是一个平衡二叉树或者红黑树,特点是数据存储是有序的存储. 参考侯杰老师的stl源码剖析,map里面采用的是RB-TREE也就是红黑树 ...

  10. 在FLASH中读写结构体

    在FLASH中读写结构体 注意事项 编程(写数据)地址要对齐 写数据时,我们要指定写入的地址,如果写入地址为非对齐,则会出现编程对齐错误. 比如遵循32位(4字节)地址对齐,你的地址只能是4的倍数.0 ...