Rust 多线程编程的实现

 更新时间:2023年12月07日 11:39:32   作者:int8  
在rust中,多线程编程不算困难,但是也需要留心和别的编程语言中不同的地方,本文主要介绍了Rust 多线程编程的实现,感兴趣的可以了解一下

一个进程一定有一个主线程,主线程之外创建出来的线程称为子线程
多线程编程,其实就是在主线程之外创建子线程,让子线程和主线程并发运行,完成各自的任务。
Rust语言支持多线程编程。

Rust语言标准库中的 std::thread 模块用于多线程编程。
std::thread 提供很很多方法用于创建线程、管理线程和结束线程。

一、创建线程

使用std::thread::spawn()方法创建一个线程。

pub fn spawn<F, T>(f: F) -> JoinHandle<T>

参数 f 是一个闭包,是线程要执行的代码。

范例

use std::thread; // 导入线程模块
use std::time::Duration; // 导入时间模块
fn main() {
     //创建一个新线程
     thread::spawn(|| {
         for i in 1..10 {
             println!("hi number {} from the spawned thread!", i);
             thread::sleep(Duration::from_millis(1));
         }
     });
     // 主线程要执行的代码
     for i in 1..5 {
         println!("hi number {} from the main thread!", i);
         thread::sleep(Duration::from_millis(1));
     }
}
编译运行结果如下
hi number 1 from the main thread!
hi number 1 from the spawned thread!
hi number 2 from the main thread!
hi number 2 from the spawned thread!
hi number 3 from the main thread!
hi number 3 from the spawned thread!
hi number 4 from the spawned thread!
hi number 4 from the main thread!

咦,执行结果好像出错了? 是吗?
当主线程执行结束,那么就会自动关闭创建出来的子线程。
上面的代码,我们调用 thread::sleep() 函数强制线程休眠一段时间,这就允许不同的线程交替执行。
虽然某个线程休眠时会自动让出cpu,但并不保证其它线程会执行。这取决于操作系统如何调度线程。
这个范例的输出结果是随机的,主线程一旦执行完成程序就会自动退出,不会继续等待子线程。这就是子线程的输出结果不全的原因。

二、让主线程等待子线程

默认情况下,主线程并不会等待子线程执行完毕。为了避免这种情况,我们可以让主线程等待子线程执行完毕然后再继续执行。

Rust标准库提供了 join() 方法用于把子线程加入主线程等待队列。

spawn<F, T>(f: F) -> JoinHandle<T>

范例

use std::thread;
use std::time::Duration;
fn main() {
     let handle = thread::spawn(|| {
         for i in 1..10 {
             println!("hi number {} from the spawned thread!", i);
             thread::sleep(Duration::from_millis(1));
         }
     });
     for i in 1..5 {
         println!("hi number {} from the main thread!", i);
         thread::sleep(Duration::from_millis(1));
     }
     handle.join().unwrap();
}
编译运行结果如下
hi number 1 from the main thread!
hi number 1 from the spawned thread!
hi number 2 from the spawned thread!
hi number 2 from the main thread!
hi number 3 from the spawned thread!
hi number 3 from the main thread!
hi number 4 from the main thread!
hi number 4 from the spawned thread!
hi number 5 from the spawned thread!
hi number 6 from the spawned thread!
hi number 7 from the spawned thread!
hi number 8 from the spawned thread!
hi number 9 from the spawned thread!

从输出结果来看,主线程和子线程交替执行。
主线程等待子线程执行完毕是因为调用了 join() 方法。

三、move强制所有权迁移

这是一个经常遇到的情况:
实例

use std::thread;
fn main() {
    let s = "hello";
   
    let handle = thread::spawn(|| {
        println!("{}", s);
    });

    handle.join().unwrap();
}

在子线程中尝试使用当前函数的资源,这一定是错误的!因为所有权机制禁止这种危险情况的产生,它将破坏所有权机制销毁资源的一定性。我们可以使用闭包的move关键字来处理:
实例

use std::thread;
fn main() {
    let s = "hello";
   
    let handle = thread::spawn(move || {
        println!("{}", s);
    });

    handle.join().unwrap();
}

四、消息传递

使用通道传递消息,通道有两部分组成,一个发送者(transmitter)和一个接收者(receiver)。
std::sync::mpsc包含了消息传递的方法:
实例

use std::thread;
use std::sync::mpsc;
fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        let val = String::from("hi");
        tx.send(val).unwrap();
    });
    let received = rx.recv().unwrap();
    println!("Got: {}", received);
}
运行结果:
Got: hi

子线程获得了主线程的发送者tx,并调用了它的send方法发送了一个字符串,然后主线程就通过对应的接收者rx接收到了。

到此这篇关于Rust 多线程编程的实现的文章就介绍到这了,更多相关Rust 多线程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解在Rust语言中如何声明可变的static类型变量

    详解在Rust语言中如何声明可变的static类型变量

    在Rust中,可以使用lazy_static宏来声明可变的静态变量,lazy_static是一个用于声明延迟求值静态变量的宏,本文将通过一个简单的例子,演示如何使用 lazy_static 宏来声明一个可变的静态变量,需要的朋友可以参考下
    2023-08-08
  • Rust 连接 PostgreSQL 数据库的详细过程

    Rust 连接 PostgreSQL 数据库的详细过程

    这篇文章主要介绍了Rust 连接 PostgreSQL 数据库的完整代码,本文图文实例代码相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01
  • vscode搭建rust开发环境的图文教程

    vscode搭建rust开发环境的图文教程

    Rust 是一种系统编程语言,它专注于内存安全、并发和性能,本文主要介绍了vscode搭建rust开发环境的图文教程,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • 详解Rust中的方法

    详解Rust中的方法

    方法其实就是结构体的成员函数,在C语言中的结构体是没有成员函数的,但是Rust毕竟也是一门面向对象的编程语言,所以给结构体加上方法的特性很符合面向对象的特点,这篇文章主要介绍了Rust中的方法,需要的朋友可以参考下
    2022-10-10
  • RUST语言函数的定义与调用方法

    RUST语言函数的定义与调用方法

    定义一个RUST函数使用fn关键字,下面通过本文给大家介绍RUST语言函数的定义与调用方法,感兴趣的朋友跟随小编一起看看吧
    2024-04-04
  • Rust如何使用config配置API

    Rust如何使用config配置API

    这篇文章主要介绍了Rust如何使用config配置API,这里记录了如何声明配置类型,读取配置,通过环境变量来覆盖配置值等开发中常见的动作,需要的朋友可以参考下
    2023-11-11
  • 关于使用rust调用c++静态库并编译nodejs包的问题

    关于使用rust调用c++静态库并编译nodejs包的问题

    这篇文章主要介绍了使用rust调用c++静态库并编译nodejs包的问题,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • 如何基于Rust实现文本搜索minigrep

    如何基于Rust实现文本搜索minigrep

    这篇文章主要介绍了基于Rust实现的文本搜索minigrep,本次演示介绍针对原作者代码程序的查询逻辑做了一点点小的优化,原程序逻辑的查询是放在了程序运行的时候,逻辑修改后启动的时候可以添加参数,也可以启动后添加,需要的朋友可以参考下
    2024-08-08
  • rust语言基础pub关键字及Some语法示例

    rust语言基础pub关键字及Some语法示例

    这篇文章主要为大家介绍了rust语言基础pub关键字及Some语法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • 深入理解Rust中Cargo的使用

    深入理解Rust中Cargo的使用

    本文主要介绍了深入理解Rust中Cargo的使用,Cargo简化了项目的构建过程,提供了依赖项管理,以及一系列方便的工作流程工具,下面就来具体的介绍一下如何使用,感兴趣的可以了解一下
    2024-04-04

最新评论