1114 按序打印

题目描述:
我们提供了一个类:
public class Foo {
public void one() { print(“one”); }
public void two() { print(“two”); }
public void three() { print(“three”); }
}
三个不同的线程将会共用一个 Foo 实例。
线程 A 将会调用 one() 方法
线程 B 将会调用 two() 方法
线程 C 将会调用 three() 方法
请设计修改程序,以确保 two() 方法在 one() 方法之后被执行,three() 方法在 two() 方法之后被执行。

示例 1:
输入: [1,2,3]
输出: “onetwothree”
解释:
有三个线程会被异步启动。
输入 [1,2,3] 表示线程 A 将会调用 one() 方法,线程 B 将会调用 two() 方法,线程 C 将会调用 three() 方法。
正确的输出是 “onetwothree”。

示例 2:

输入: [1,3,2]
输出: “onetwothree”
解释:
输入 [1,3,2] 表示线程 A 将会调用 one() 方法,线程 B 将会调用 three() 方法,线程 C 将会调用 two() 方法。
正确的输出是 “onetwothree”。

注意:
尽管输入中的数字似乎暗示了顺序,但是我们并不保证线程在操作系统中的调度顺序。
你看到的输入格式主要是为了确保测试的全面性。

方法1:使用信号量
主要思路:
(1)使用信号量实现函数之间的同步有序进行;
(2)将两个信号量的初始值置为0,当第一个函数完成后,对信号量1进行post操作,对于第二个函数阻塞在信号量1,既进入函数后,对信号量1进行wait操作,完成第二个函数后,对第二个信号量进行post操作,对于第三个函数,阻塞在第二个信号量,既进入函数后,对信号量 2进行wait操作;
(3)注意头文件的添加

#include <semaphore.h>

class Foo {
public:
    sem_t  first_job_done;
    sem_t  second_job_done;
    Foo() {
        sem_init(&first_job_done,0,0);
        sem_init(&second_job_done,0,0);
    }

    void first(function<void()> printFirst) {
        
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        sem_post(&first_job_done);
    }

    void second(function<void()> printSecond) {
        sem_wait(&first_job_done);
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        sem_post(&second_job_done);
    }

    void third(function<void()> printThird) {
        sem_wait(&second_job_done);
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }
};

方法2:使用volatile变量实现简单的同步
主要思路:
(1)使用volatile 的bool变量,配合while实现死循环的阻塞,模仿信号量,实现同步;
(2)但过于耗时,特别是在单核的时候;

class Foo {
public:
	//volatile变量保证变量不被编译器优化
    volatile bool first_job_done;
    volatile bool second_job_done;
    Foo() {
        first_job_done=false;
        second_job_done=false;
    }

    void first(function<void()> printFirst) {
        
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
        first_job_done=true;//解开死循环。保证同步有序
    }

    void second(function<void()> printSecond) {
        while(!first_job_done);//死循环模仿阻塞
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
        second_job_done=true;
    }

    void third(function<void()> printThird) {
        while(!second_job_done);
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值