当前位置: 首页 > news >正文

白云区建网站公司杭州定制网站制作

白云区建网站公司,杭州定制网站制作,如何自己弄一个网站,wordpress divi 悬浮Rust多线程编程 文章目录 Rust多线程编程使用线程模块创建线程线程传参闭包#xff08;匿名函数#xff09;值捕获不可变引用捕获可变引用捕获 线程闭包传参更优雅地传参 回收线程线程同步和通信channel 通道mutex 互斥锁Barrier 栅栏Atomic Types 原子类型 使用线程模块 ru…Rust多线程编程 文章目录 Rust多线程编程使用线程模块创建线程线程传参闭包匿名函数值捕获不可变引用捕获可变引用捕获 线程闭包传参更优雅地传参 回收线程线程同步和通信channel 通道mutex 互斥锁Barrier 栅栏Atomic Types 原子类型 使用线程模块 rust标准库中提供了线程相关支持直接引用即可使用 use std::thread;创建线程 使用spawn方法创建一个线程。如 use std::thread;/* 引用线程模块 */ use std::time::Duration; fn main() {std::thread::spawn(thread_function);loop {thread::sleep(Duration::from_secs(1));/* sleep 1s */println!(main thread running..);} }fn thread_function(){loop {thread::sleep(Duration::from_secs(1));/* sleep 1s */println!(demo thread running..);} }创建后线程自动运行 boysserver:~/rust_study/demo$ cargo runCompiling demo v0.1.0 (/home/boys/rust_study/demo)Finished dev [unoptimized debuginfo] target(s) in 0.39sRunning target/debug/demo main thread running.. demo thread running.. main thread running.. demo thread running.. main thread running.. demo thread running.. ^C boysserver:~/rust_study/demo$ 线程传参 默认的spawn方法传递不了参数。如果要为线程传递参数需要使用匿名函数作为spawn的参数匿名函数也称为闭包。 闭包匿名函数 闭包的基本语法 |param1, param2, ...| {// 函数体 }使用闭包的好处是可以捕获函数体外的变量传递到函数体内。 按捕获变量方式可以分为 值捕获普通引用捕获可变引用捕获 值捕获 值捕获的方式会变量的所有权会转移到闭包内外部无法再使用。如 fn main(){let str String::from(hello);let closure_print_string move ||{/* move表明函数体内捕获的变量使用值捕获方式 */println!(number {}, str);/* 使用值捕获方式捕获外部的str */};closure_print_string();println!(test for str: {}, str);/* 值捕获方式str的所有权已经被转移到闭包内这里无法再使用 */ }不可变引用捕获 闭包会自动识别捕获的变量类型。根据函数体内捕获的变量的类型确认捕获方式。 不可变变量按照不可变引用方式捕获使用因此无法修改原变量值只能访问变量值。如 fn main(){let str String::from(hello);/* str是不可变 */let closure ||{println!(str: {}, str);// str.push_str(world);/* 不可变的变量按不可变引用方式捕获此处修改了变量值会报错 */};closure();println!(test for str: {}, str); }可变引用捕获 将外部变量变为可变变量即可在闭包函数体内修改变量的值。 fn main(){let mut str String::from(hello);/* str是不可变 */let mut closure ||{println!(before push, str: {}, str);str.push_str( world);/* 不可变的变量按不可变引用方式捕获此处修改了变量值会报错 */};closure();println!(test for str: {}, str); }同时闭包的类型也要定义为mut可变的。只要捕获外部的可变变量都是定义为mut的。如 fn main(){let num 123;let mut str String::from(hello);/* str是不可变 */let mut closure ||{println!(num: {}, num);/* num不可变 */println!(before push, str: {}, str);str.push_str( world);/* 不可变的变量按不可变引用方式捕获此处修改了变量值会报错 */};closure();println!(test for str: {}, str); }线程闭包传参 现在就可以使用闭包的方法将外部参数传递给线程了。 如 fn main(){let word what are words;let thread_handle std::thread::spawn(move ||{println!(just print word: {}, word);});thread_handle.join().unwrap(); }这里必须使用值捕获方式将字符串引用变量str的所有权转移到闭包内。因为编译时会检查闭包和当前函数的声明周期发现闭包可能会在当前的函数结束后运行因为闭包传递到了另一个线程。 closure may outlive the current function, but it borrows word, which is owned by the current function更优雅地传参 通过闭包虽然可以传递外部参数到另一个线程但闭包一般都用来实现比较简单的功能。对于线程来说会有比较复杂的功能所以更优雅的方式还是使用函数对一个线程做封装后再闭包传递参数创建线程。如 use std::time::Duration; struct ThreadParam{thread_name: String } fn demo_thread(param: ThreadParam){for _ in 0..3{/* 使用下划线作为迭代变量避免编译警告 */std::thread::sleep(Duration::from_secs(1));println!(threads name: {}, param.thread_name);} } fn main(){let thread_arguments ThreadParam{thread_name: String::from(demo_thread)};let thread_handle std::thread::spawn(move ||{demo_thread(thread_arguments);});thread_handle.join().unwrap();/* 回收线程防止主线程退出看不到线程效果 */ }回收线程 使用join方法回收线程资源。如 use std::thread;/* 引用线程模块 */ use std::time::Duration; fn main() {let thread_handle std::thread::spawn(thread_function);thread_handle.join().unwrap();println!(thread exit.); }fn thread_function(){let mut count 1;loop {thread::sleep(Duration::from_secs(1));/* sleep 1s */println!(demo thread run {} time.., count);count count 1;if count 3 {break;}} }boysserver:~/rust_study/demo$ cargo runFinished dev [unoptimized debuginfo] target(s) in 0.00sRunning target/debug/demo demo thread run 1 time.. demo thread run 2 time.. demo thread run 3 time.. thread exit.线程同步和通信 rust线程同步和通信提供了几种自带的机制 channel通道Mutex互斥锁原子类型Atomic Types条件变量Condition Variable原子引用计数Arc栅栏Barrier channel 通道 通道只能使用在多生产者、单消费者的场景下所在模块是 std::sync::mpscmpsc是Multi-Producer, Single-Consumer 的缩写即多生产者单消费者。 use std::sync::mpsc;使用示例 fn main(){let (sender, receiver) std::sync::mpsc::channel();let sender1 sender.clone();/* 通过克隆2个sender传递到线程中 */let sender2 sender.clone();let sender1_thread_handle std::thread::spawn(move||{std::thread::sleep(std::time::Duration::from_secs(1));sender1.send(hello).unwrap();});let sender2_thread_handle std::thread::spawn(move||{std::thread::sleep(std::time::Duration::from_secs(2));sender2.send(bye).unwrap();});let mut is_connected false;loop {let recv_data receiver.recv().unwrap();if recv_data hello{println!(recv hello, connected);is_connected true;}if is_connected true{if recv_data bye{println!(recv bye, disconnected);break;}}}sender1_thread_handle.join().unwrap();sender2_thread_handle.join().unwrap(); }mutex 互斥锁 导入模块 use std::sync::Mutex;Rust 中的互斥锁Mutex是一个泛型类型。它被定义为 std::sync::MutexT其中的 T 是要保护的共享数据的类型。初始化时会自动判断数据类型。 下面是使用Mutex对整形变量做互斥访问的示例 use std::sync::{Mutex, Arc}; use std::thread;fn main() {let data Arc::new(Mutex::new(42));let thread1_data Arc::clone(data);let handle1 thread::spawn(move || {// 使用 thread1_data 进行操作let mut value thread1_data.lock().unwrap();*value 1;println!(thread1 Value: {}, *value);});let thread2_data Arc::clone(data);let handle2 thread::spawn(move || {// 使用 thread2_data 进行操作let value thread2_data.lock().unwrap();println!(thread2 Value: {}, *value);});handle1.join().unwrap();handle2.join().unwrap(); }这里使用了Arc原子引用计数类型实现多个线程共享互斥锁的所有权。 Barrier 栅栏 在 Rust 中你可以使用 Barrier 类型来实现线程栅栏。 Barrier 允许一组线程都到达一个点后再同时继续执行。 示例 use std::sync::{Arc, Barrier}; use std::thread;fn main() {let barrier Arc::new(Barrier::new(3)); // 创建一个包含3个参与者的栅栏for i in 0..3 {/* 创建3个线程 *//* 使用Arc原子引用计数将barrier共享给所有线程 */let barrier_clone Arc::clone(barrier);thread::spawn(move || {println!(Thread {} before barrier, i);barrier_clone.wait(); // 所有线程都到达此处后会同时继续执行println!(Thread {} after barrier, i);});}thread::sleep(std::time::Duration::from_secs(2)); // 等待足够的时间以确保所有线程完成println!(Main thread); }Atomic Types 原子类型 Rust中常用的原子类型有 AtomicBool 原子布尔类型AtomicI32 原子整数类型AtomicPtr 原子指针类型 原子类型是不可分割的类型对原子类型变量的操作不可分割因此常用在多线程并发场景避免出现竞态问题。 简单的使用示例 use std::sync::atomic::{AtomicI32, Ordering}; use std::sync::Arc; use std::thread;fn main() {let atomic_counter Arc::new(AtomicI32::new(0));let mut handles vec![];/* 使用vec保存线程句柄回收资源使用 */for _ in 0..5 {let counter Arc::clone(atomic_counter);let handle thread::spawn(move || {for _ in 0..1_0 {counter.fetch_add(1, Ordering::SeqCst);}});handles.push(handle);}for handle in handles {handle.join().unwrap();}println!(Final value: {}, atomic_counter.load(Ordering::SeqCst)); }创建了5个线程对原子变量进行递增10次输出结果为50。若未使用原子变量且不加互斥保护得到的结果是未知的。 boysserver:~/rust_study/demo$ cargo run Compiling demo v0.1.0 (/home/boys/rust_study/demo)Finished dev [unoptimized debuginfo] target(s) in 0.39sRunning target/debug/demo Final value: 50
http://www.hkea.cn/news/14557625/

相关文章:

  • 中国联通网站建设与维护网站建设空间一般多大
  • 心理教育网站建设目的合伙开公司建设网站被骗
  • 百度移动网站检测英文版wordpress如何转换
  • 沙坪坝做网站查域名注册详细信息查询
  • 鞋 东莞网站建设 技术支持企业宣传网站有哪些
  • 中国空间站完成图濮阳市建设工程交易网
  • 网站搜索怎么做广州网站建设哪家公司
  • 学建设网站lnmp wordpress
  • 住建部建设厅官方网站为企业做贡献演讲稿
  • 建筑公司网站需求wordpress 视频 广告插件
  • 自助网站建设系统源码南通网站seo报价
  • 深圳平湖网站建设公司响应式网站开发报价
  • 松江建网站建立个人免费网站
  • 个人网站什么好泰安市泰山区招聘信息
  • 大型网站 解决方案 技术网站怎么做防御
  • 福州优化网站建设玛迪做网站
  • 汽车金融网站怎么做wordpress留言板源码
  • 织梦如何制作静态网站模板骨干专业群建设任务书网站
  • 免费个人网站建设制作代码官方网站建设方案图
  • 如何创建公司网站做标签网站是干嘛的
  • 餐饮行业做网站的好处电子商务网站建设与管理读书心得
  • 百度地图电脑版网页优化服务公司
  • 网站怎么做网上报名行业网站 源码
  • 八步网站建设简洁大气的企业网站
  • 最简单的网站系统ui设计
  • 网站布局分类个人创建网站程序
  • 织梦后台怎么做网站地图什么网页可以做网站
  • 网站推广预期达到的目标wordpress前台打不开
  • 定制制作网站设计黄骅港旅游景点大全海边
  • 阿里云快速做网站烟台网站建设找企汇互联专业