7.22. Rust concurrent programming

发布时间 : 2025-10-25 13:33:19 UTC      

Page Views: 9 views

Safe and efficient processing of concurrency is one of the purposes of Rust,which mainly solves the problem of high load bearing capacity of the server.

The concept of concurrent refers to the independent execution of different parts of the program, which is easily confused with the concept of parallel,which emphasizes “simultaneous execution”.

Concurrency often leads to parallelism.

This chapter describes programming concepts and details related to concurrency.

7.22.1. Thread #

A thread is a part of a program that runs independently.

The difference between a thread and a process (process) is that a thread is a concept within a program, and a program is often executed in a process.

In an environment with an operating system, processes are often scheduled alternately to execute, and threads are scheduled by the program within the process.

As thread concurrency is likely to occur in parallel, deadlocks and delay errors that may be encountered in parallelism often occur in programs with concurrency mechanisms.

In order to solve these problems, many other languages (such as Java, C #) use special runtime software to coordinate resources, but this undoubtedly greatly reduces the efficiency of program execution.

Multi-threading is also supported at the bottom of the operating system, andthe language itself and its compiler do not have the ability to detect and avoid parallel errors, which is very stressful for developers. Developers need to spend a lot of energy to avoid errors.

Rust does not depend on the run-time environment, as is the case with CplinkCure +.

But Rust has designed tools in the language itself, including ownership mechanisms, to eliminate as many common errors as possible in the compilation phase, which is not available in other languages.

But this does not mean that we can be careless when programming, so far the problems caused by concurrency have not been completely solved in the publicdomain, there may still be errors, concurrent programming should be as careful as possible!

Pass through Rust std::thread::spawn function to create a new thread:

Example #

use std::thread; use std::time::Duration; fn spawn_function() { for i in 0..5 { println!("spawned thread print {}", i); thread::sleep(Duration::from_millis(1)); } } fn main() { thread::spawn(spawn_function); for i in 0..3 { println!("main thread print {}", i); thread::sleep(Duration::from_millis(1)); } } 

Running result:

main thread print 0 spawned thread print 0 main thread print 1 spawned thread print 1 main thread print 2 spawned thread print 2 

The order of this result may change in some cases, but in general it is printed like this.

This program has a child thread designed to print five lines of text, and the main thread prints three lines of text, but obviously with the end of the main thread spawn , the thread ends and does not complete all the printing.

std::thread::spawn : The parameter of the function is a no-parameter function, but the above method is not recommended. We can use closures to pass the function as a parameter:

Example #

use std::thread; use std::time::Duration; fn main() { thread::spawn(\|\| { for i in 0..5 { println!("spawned thread print {}", i); thread::sleep(Duration::from_millis(1)); } }); for i in 0..3 { println!("main thread print {}", i); thread::sleep(Duration::from_millis(1)); } } 

Closures are anonymous functions that can be saved into variables or passed as arguments to other functions. The closure is equivalent to the Lambda expression in Rust in the following format:

|Parameter 1, Parameter 2,... | -> Return value type{ //Function body } 

For example:

Example #

fn main() { let inc = \|num: i32\| -> i32 { num + 1 }; println!("inc(5) = {}", inc(5)); } 

Running result:

inc(5) = 6 

Closures can omit type declarations using the Rust automatic type determination mechanism:

Example #

fn main() { let inc = \|num\| { num + 1 }; println!("inc(5) = {}", inc(5)); } 

The result has not changed.

7.22.2. Join method #

Example #

use std::thread; use std::time::Duration; fn main() { let handle = thread::spawn(\|\| { for i in 0..5 { println!("spawned thread print {}", i); thread::sleep(Duration::from_millis(1)); } }); for i in 0..3 { println!("main thread print {}", i); thread::sleep(Duration::from_millis(1)); } handle.join().unwrap(); } 

Running result:

main thread print 0 spawned thread print 0 spawned thread print 1 main thread print 1 spawned thread print 2 main thread print 2 spawned thread print 3 spawned thread print 4 

join method can cause the child thread to finish running and then stop running the program.

7.22.3. Move forced ownership transfer #

This is a common situation:

Example #

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

It must be wrong to try to use the resources of the current function in the child thread! Because the ownership mechanism prohibits the emergence of such a dangerous situation, it will undermine the certainty of the destruction of resources by the ownership mechanism. We can use closures. move keyword to handle:

Example #

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

7.22.4. Message passing #

One of the main tools to achieve message passing concurrency in Rust is channel, which consists of two parts, a sender (transmitter) and a receiver (receiver).

std::sync::mpsc Contains methods for message delivery:

Example #

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); } 

Running result:

Got: hi 

The child thread got the sender of the main thread tx and called its send method sends a string, and the main thread passes through the corresponding receiver rx got it.

《地理信息系统原理、技术与方法》  97

最近几年来,地理信息系统无论是在理论上还是应用上都处在一个飞速发展的阶段。 GIS被应用于多个领域的建模和决策支持,如城市管理、区划、环境整治等等,地理信息成为信息时代重要的组成部分之一; “数字地球”概念的提出,更进一步推动了作为其技术支撑的GIS的发展。 与此同时,一些学者致力于相关的理论研究,如空间感知、空间数据误差、空间关系的形式化等等。 这恰好说明了地理信息系统作为应用技术和学科的两个方面,并且这两个方面构成了相互促进的发展过程。