我们提供了一个类:

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. mfc HackerTools监控键盘按键

    string GetKey(int Key) { string KeyString = ""; //判断符号输入 const int KeyPressMask = 0x800000 ...

  2. 六:使用Cookie进行会话管理

    1.存储客户端的状态 因为Http协议是无状态的,也就是说每个客户访问服务器端资源时,服务器并不知道该客户端是谁,所以需要会话技术识别客户端的状态.会话技术是帮助服务器 记住客户端状态 2.会话技术 ...

  3. 入门数据结构与算法,看这一个就够了,知识点+LeetCode实战演练

    本笔记来自拉钩教育300分钟搞定算法面试 算法与数据结构 要掌握一种数据结构,就必须要懂得分析它的优点和缺点. 在考虑是否应当采用一种数据结构去辅助你的算法时,请务必考虑它的优缺点,看看它的缺点是否会 ...

  4. 进程CPU、内存过高问题查找

    1.定位进程 找出占用CPU最高的10个进程 ps aux | sort -k3nr | head -n 10 查看占用内存最高的10个进程 ps aux | sort -k4nr | head -n ...

  5. java实现全排列输出

    java实现全排列输出 转自:http://easonfans.iteye.com/blog/517286 最近在找工作,面试java程序员或者软件工程师,在笔试的时候常常见到这么一道题:全排列 的输 ...

  6. springboot @value无法赋值

    1解决方式在类上在加@Compent @Component@EnableBinding(Sink.class)public class ReceiveMessageListenerController ...

  7. 新东方集团K12公益免费课战役记

    作者:张建鑫, 曾任IBM高级软件架构师, 滴滴高级技术专家, 现任新东方集团高级技术总监 1月31日,集团领导决定由产品技术中心的新东方APP团队牵头做周一到周五的集团公益课, 提供给全国中小学生使 ...

  8. centos7 查看端口占用情况

    2021-08-02 1. 查看端口占用情况 # 查看 8088 端口占用情况 lsof -i tcp:8088 # 若提示没有 lsof 命令, yum 安装一下 yum -y install ls ...

  9. Python之pyyaml模块

    pyyaml模块在python中用于处理yaml格式数据,主要使用yaml.safe_dump().yaml.safe_load()函数将python值和yaml格式数据相互转换.当然也存在yaml. ...

  10. Linux常用命令 - less命令详解

    21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html 查看文 ...