C++ 多线程(4) 信号量、async、future_status、shared_future、packaged_task、promise

1.首先信号量是与互斥量配合使用的,使用wait()可以放弃锁,等待其它线程唤醒后(使用notify_all()或者notify_one())再继续获得锁。当然wait()函数是可以有第二个参数的,第二个参数可以是任何的可执行对象,这样被唤醒后不会直接参与锁的竞争而是先去检查第二个参数是否返回true,如果返回false则会继续等待,只不过此时的等待是在醒着的状态下。
2.等待可以使用另一个函数wait_for(),可以在wait的基础上多加一个参数即时间,如果直到时间截止前的这一段时间内(没有被唤醒)或者(唤醒后可执行对象一直检查为false)那么会直接退出wait_for,不在阻塞继续往下执行
3.async、packaged_task、promise都会返回future对象,用来异步的获取执行结果。
3.1 async用于开启一个异步任务
3.1.1如果使用launch::async参数会立即创建一个线程执行(在async的语句发生时就执行)。
3.1.2如果使用launch::deferred不会立即执行,如果一直不调用future对象一直不调用get或者wait函数,那么就永远不会执行对应函数。直到使用get或者wait函数会阻塞执行相应的函数此时的话很有可能是在本线程直接执行相应的函数。
3.1.3如果不带参数或者使用launch::async | launch::deferred参数,那么具体是用上述那种方式会根据情况而定(视资源的使用情况),如果说我想知道具体是哪种方式执行的,可以使用future_status进行查看,具体代码如下:
	std::future<int> myfuture = std::async(my_print);
    std::future_status myfuture_status = myfuture.wait_for(std::chrono::milliseconds(0));
    if (myfuture_status == std::future_status::deferred)
    {
        std::cout << "延迟执行" << std::endl;
        std::cout << myfuture.get() << std::endl;
    }
    else if (myfuture_status == std::future_status::ready)
    {
        std::cout << "执行结束" << std::endl;
        std::cout << myfuture.get() << std::endl;
    }
    else if (myfuture_status == std::future_status::timeout)
    {
        std::cout << "执行还未结束" << std::endl;
        std::cout << myfuture.get() << std::endl;
    }
3.1.4 综上,async是会创建一个异步任务的,而且如果使用launch::deferred参数的话,你不调用get或者wait的话是不会阻塞的,就相当于你这个async没创建,没用;同时如果你使用的是launch::async那么从这个async创建完成便开始执行,即使你不使用get或者wait在退出作用域析构时还是会阻塞执行。这一点需要注意。
3.2 packaged_task这个可以包装一个可执行对象,它的返回结果也是future,它是比较灵活的,直到你希望执行的时候它才执行,并且也可以通过get获得结果。
3.3 promise非常好用,它也是返回future,我们可以在一个线程中使用get函数阻塞获取结果,然后在另一个线程中随便执行直到把结果求到之后通过promise的set_value函数把结果放入供需要的线程使用。
4 shared_future可以将结果共享,从而解决future对象其中一个使用get后其他人再使用get也获取不到值了。
void thread_func(const std::shared_future<int>& sf1)
{
    std::cout << "线程ID:" << std::this_thread::get_id() << "结果为" << sf1.get() << std::endl;
}
int main()
{
    std::promise<int> mypromise;
    std::shared_future<int> sf = mypromise.get_future();
    std::thread thread1(thread_func, std::ref(sf));
    std::thread thread2(thread_func, std::ref(sf));
    std::this_thread::sleep_for(std::chrono::microseconds(5000));
    mypromise.set_value(5);
    thread1.join();
    thread2.join();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值