C++ Boost Thread和Rust Thread对比

来源:互联网 发布:asp.net高级编程 pdf 编辑:程序博客网 时间:2024/06/08 07:42

C++11新加入的std::thread是由boost::thread发展而来,二者用法极其相似,基本上就是改一下头文件和名称空间的问题,例外是thread_group,thread_group,它们都是boost的组件,但并不是标准库的组件,所以需要自己实现一下。还有boost中的thread_group使用shared_mutex来进行线程同步,shared_mutex也没有进入标准库,所以需要用什么东西来替代一下。shared_mutex没能进入标准库的原因就是C++标准化委员会认为目前可行的shared_mutex实现方案在性能上并不合算,不如直接使用mutex,既然如此,就直接用mutex吧,相应的shared_lock也修改成lock_guard即可。
本文就用boost::thread为例来简要说下C++的线程库,然后和Rust的线程库进行简要对比:
一.创建线程:

//编译: g++ -Wall thread01.cpp -lboost_thread -o thread01 -lboost_system//执行:./thread01#include <boost/thread/thread.hpp>#include <iostream>using namespace boost;void test(){    std::cout<<"hello world!"<<std::endl;}int main(int argc, char const *argv[]) {    boost::thread  t1(&test);    t1.join();    return 0;}

使用std::thread库的代码几乎和上面一模一样:

//编译:g++ -std=c++11 thread001.cpp -lpthread -o thread001//执行:./thread001#include <thread>#include <iostream>using namespace std;void test(){    std::cout<<"hello world!"<<std::endl;}int main(int argc, char const *argv[]) {    std::thread  t1(&test);    t1.join();    return 0;}

上面代码中的thread()会构造一个表示当前执行线程的线程对象t1,这个thread对象把test作为它的起始函数。新建了一个新线程t1之后,程序就有两个线程:主线程和t1线程:主线程起始于main()函数而t1线程起始于test()函数。
如果t1启动之后,主线程什么也不管往下执行,它就会一口气运行到main()结束,从而结束整个程序。所以我们需要调用一个join()函数来等待这个新线程的执行过程。join()是个简单暴力的方法:新线程调用join()之后,主线程会一直等待新进程,直到新线程执行完毕(Waits for this thread to die)。

Rust 的标准库为线程提供了一个库,它允许你以并行的方式运行 Rust 代码。这里是使用 std::Thread 的一个简单例子:

//thread01.rs//编译:rustc thread01.rs//执行:./thread01use std::thread;fn main() {    let t = thread::spawn(move || {        "Hello from a thread!"    });    println!("{}", t.join().unwrap());}

Rust创建线程的方法可以总结为:

use std::thread;thread::spawn(move || {    // 这里是新建线程的执行逻辑});

thread:spawn() 方法接受一个封闭参数,这个参数会在一个新线程中执行。它返回该线程的句柄,它可以用来在等待子线程完成之后提取其结果。
默认情况下,新创建的子线程与原先的父线程是分离的关系。也就是说,子线程可以在父线程结束后继续存在,除非父线程是主线程。因为我们知道,如果一个进程的主线程也退出了,这个进程就会终止,其它所有线程都会随之结束。

如果我们需要等待子线程执行结束,那么可以使用join方法:

//thread02.rs//编译:rustc thread02.rs//执行:./thread02use std::thread;// child 的类型是 JoinHandle<T>,这个T是什么呢,当然是闭包的返回类型了fn main() {    let child = thread::spawn(move || {    "hello world"    });    let res = child.join();// 父线程等待子线程结束    println!("{}", res.unwrap());}
原创粉丝点击