1. はじめに
Rust でスレッドを使う処理の確認を行いました。
参考した スレッドを使用してコードを同時に走らせる では main() 内にスレッドを作成し終了まで待つ処理でしたが、あくまでもサンプルなのでそのまま使うことはまずないため、スレッドの開始と終了を行う関数を作成し、ついでに複数のスレッドが動作するようにしてみました。
2. 以下、ソース
use std::thread;
use std::time::Duration;
mod threads {
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
use std::thread::{self, JoinHandle};
use std::time::Duration;
// スレッドのハンドルと停止フラグを保持する構造体
// 動作確認用にメッセージも保持する
pub struct ThreadHandle {
handle: JoinHandle<()>,
stop_flag: Arc<AtomicBool>,
msg: String,
}
pub fn start(msg: String) -> ThreadHandle {
println!("Thread started : {}", msg);
// Arc でスレッド間で共有するためのフラグを作成
let stop_flag = Arc::new(AtomicBool::new(false));
let stop_flag_clone = Arc::clone(&stop_flag);
let msg_clone = msg.clone();
// handle にスレッドのハンドルを保持
let handle = thread::spawn(move || {
let mut i = 1;
// stop_flag が true になるまでループ
while !stop_flag_clone.load(Ordering::Relaxed) {
println!("{}: hi number {} from the spawned thread!", msg_clone, i);
thread::sleep(Duration::from_millis(1000));
i += 1;
}
});
// スレッドのハンドルと停止フラグを保持する構造体を返す
ThreadHandle { handle, stop_flag, msg }
}
// ThreadHandle を引数として受け取り、指定のスレッドを停止する
pub fn stop(thread_handle: ThreadHandle) {
// スレッドを停止するためにフラグを true にする
thread_handle.stop_flag.store(true, Ordering::Relaxed);
// スレッドの終了を待つ
thread_handle.handle.join().unwrap();
println!("Thread stopped : {}", thread_handle.msg);
}
}
fn main() {
// thread::sleep() でスレッドの開始と終了を確認しやすくする
let handle1 = threads::start("Handle 1".to_string());
thread::sleep(Duration::from_millis(1000));
let handle2 = threads::start("Handle 2".to_string());
thread::sleep(Duration::from_millis(5000));
threads::stop(handle1);
thread::sleep(Duration::from_millis(2000));
threads::stop(handle2);
}
3. まとめ
このコードにたどり着くまでに、Github Copilot にループにする方法、複数のスレッドを動かす方法、スレッドの停止方法などを提案してもらいました。
不具合の修正も提案してもらい、コードについてはほぼ提案通りの形を採用しました。
コメントを追加したくらいですかね。しかもコメントも補完してくれました。
最近はコードを記述する技術より指示を出す技術が上がっていく気がしています。
今回の記事も、Github Copilot が8割くらい書いてくれました。
コメント