1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

今年の言語はRust その63

Posted at

今年の言語はRust その63

Rustを学びます

Rustの日本語ドキュメント 2nd Edition
https://doc.rust-jp.rs/book/second-edition/

オリジナル(英語)
https://doc.rust-lang.org/book/

実行環境

$ cargo -V
cargo 1.33.0 (f099fe94b 2019-02-12)

$ rustup -V
rustup 1.17.0 (069c88ed6 2019-03-05)

$ rustc --version
rustc 1.33.0 (2aa4c46cf 2019-02-28)

$  cat /proc/version
Linux version 4.14.97-74.72.amzn1.x86_64 (mockbuild@gobi-build-64002) 
(gcc version 7.2.1 20170915 (Red Hat 7.2.1-2) (GCC)) 
# 1 SMP Tue Feb 5 20:59:30 UTC 2019

$ uname -a
Linux ip-10-100-0-8 4.14.97-74.72.amzn1.x86_64 
# 1 SMP Tue Feb 5 20:59:30 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

$ cat /etc/\*release
NAME="Amazon Linux AMI"
VERSION="2018.03"
ID="amzn"
ID_LIKE="rhel fedora"
VERSION_ID="2018.03"
PRETTY_NAME="Amazon Linux AMI 2018.03"
ANSI_COLOR="0;33"
CPE_NAME="cpe:/o:amazon:linux:2018.03:ga"
HOME_URL="http://aws.amazon.com/amazon-linux-ami/"
Amazon Linux AMI release 2018.03

20. マルチスレッドのWebサーバーを構築する

やっとここまで来ました。最後の章です。

実はWebサーバーの仕組みが知りたくて知りたくて60回もやってきました。

以下がレッスン内容になります

  • TCPとHTTPについて少し学ぶ。
  • ソケットでTCP接続をリッスンする。
  • 少量のHTTPリクエストを構文解析する。
  • 適切なHTTPレスポンスを生成する。
  • スレッドプールでサーバのスループットを強化する。

20.3 優雅なシャットダウンと片付け

ThreadPoolDropトレイトを実装する


/// Dropの実装
impl Drop for ThreadPool {
	fn drop(&mut self) {
		for worker in &mut self.workers {
			println!("Shutting down worker {}", worker.id);
			worker.thread.join().unwrap();
		}
	}
}

まず、これはコンパイルエラーになる

>cargo check
    Checking hello v0.1.0 (H:\Dropbox\07_DevelopFolda\20190502_Rust\hello)
error[E0507]: cannot move out of borrowed content
  --> src\lib.rs:71:4
   |
71 |             worker.thread.join().unwrap();
   |             ^^^^^^^^^^^^^ cannot move out of borrowed content

error: aborting due to previous error

For more information about this error, try `rustc --explain E0507`.
error: Could not compile `hello`.

To learn more, run the command again with --verbose.

workerへは可変参照しかない。join()は所有権を奪うので、エラーとなる。

Workerの視点で考えると。Worker.threadNoneを許容できない。
つまり、join()により所有権が奪われるとthread=Noneとなってしまうのでコンパイラに怒られるのだ。

Worker.threadにNoneを許すのであれば、Optionを使用するのがよい。

struct Worker {
	id: usize,
	thread: thread::JoinHandle<()>,
}

書き換える

struct Worker {
	id: usize,
	thread: Option<thread::JoinHandle<()>>,
}

Workerの生成時にSomeで囲います

impl Worker {
	fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>> ) -> Worker {

		// -- snip --

		Worker {
			id,
			thread: Some(thread)
		}
	}
}

Option型なので、if let構文を使って値を取り出します。
Noneの場合は、動きません。C++等でおなじみのnull回避のケースですね。

/// Dropの実装
impl Drop for ThreadPool {
	fn drop(&mut self) {
		for worker in &mut self.workers {
			println!("Shutting down worker {}", worker.id);

			if let Some(thread) = worker.thread.take() {
				thread.join().unwrap();
			}
		}
	}
}

スレッドに仕事をリッスンするのを止めるように通知する

/// スレッドの動作についての通知
enum Message {
	NewJob(Job),
	Terminate,
}

pub struct ThreadPool{
	workers: Vec<Worker>,
	sender: mpsc::Sender<Message> // Messageを送るSenderのこと
}

impl ThreadPool {

	pub fn execute<F>(&self, f: F)
		where F: FnOnce() + Send + 'static
	{
		let job = Box::new(f);

		// [-] self.sender.send(job).unwrap();
		self.sender.send(Message::NewJob(job)).unwrap(); // [+]
	}
}

impl Worker {
	fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Message>>> ) -> Worker {

		let thread = thread::spawn(move || {

			loop {
				let message = receiver.lock().unwrap().recv().unwrap();

				// receiverにより、(senderから)受け取ったメッセージにより動作を決める
				match message {
					Message::NewJob(job) => {
						println!("Worker {:?} got a job; executing.", id);

						job.call_box();
					},
					Message::Terminate => {
						println!("Worker {:?} was told to terminate", id);

						break; // ループ終了
					}
				}
			}

		});

		Worker {
			id,
			thread: Some(thread)
		}
	}
}

まとめ

サーバーの実装を甘く見積もっていた。
ほとんどは非同期処理についてでした。
サンプルを通しただけではうまく理解できなかった

自転車本届いたので、別の側面から勉強を続けようと思う。

以上!

あと、5/8にRustの最新本がでるみたいです! 気が付いてラッキー!購入しました。 (現在5/9)

実践Rust入門[言語仕様から開発手法まで] 単行本(ソフトカバー) – 2019/5/8

※アフェっときます

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?