我们提供了一个类:

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. 防止XSS 攻击集成springboot

    1.配置相关数据 在配置文件中配置 # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice/* # 匹 ...

  2. gdb调试用命令与一般调试方法

    示例代码 1 #include <iostream> 2 using namespace std; 3 4 void Print() 5 { 6 cout<<"hel ...

  3. 使用javascript纯前端导出excel

    前言(感谢技术的分享者) 参考博客地址 github地址 由SheetJS出品的js-xlsx是一款非常方便的只需要纯JS即可读取和导出excel的工具库,功能强大,支持格式众多,支持xls.xlsx ...

  4. linnux安装多台redis

    安装: 1.获取redis资源 wget http://download.redis.io/releases/redis-4.0.8.tar.gz 2.解压 tar xzvf redis-4.0.8. ...

  5. CSS中定位问题

    通过使用 position 属性,我们可以选择 4 种不同类型的定位,这会影响元素框生成的方式. position 属性值的含义: static 元素框正常生成.块级元素生成一个矩形框,作为文档流的一 ...

  6. Python - 面向对象编程 - 公共属性、保护属性、私有属性

    公共属性 在 Python 的类里面,所有属性和方法默认都是公共的 class PoloBlog: # 公共属性 sum = 0 # 构造方法 def __init__(self, name): se ...

  7. SpEL表达式注入漏洞学习和回显poc研究

    目录 前言 环境 基础学习和回显实验 语法基础 回显实验 BufferedReader Scanner SpEL漏洞复现 低版本SpringBoot中IllegalStateException CVE ...

  8. centos7 wget安装Tomcat7

    2021-07-15 1.环境介绍 操作系统:centos7 jdk版本:jdk1.8.0.211 tomcat版本:tomcat7.0.109 2. 检查系统中是否已经安装 jdk ,如未安装, 请 ...

  9. 使用Keepalived实现Nginx的自动重启及双主热备高可用

    1.概述 之前我们使用Keepalived实现了Nginx服务的双机主备高可用,但是有几个问题没有解决,今天一起探讨一下. 1)在双机主备机制中,Keepalived服务如果宕了,会自动启用备机进行服 ...

  10. 痞子衡嵌入式:MCUXpresso IDE下将应用程序RW段分散链接的几种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso IDE下将应用程序RW段分散链接的几种方法. 早期的 MCU 芯片,一般都会嵌入内部 Flash 和 RAM,并且 ...