質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

908閲覧

C++ マルチスレッド

00_x9925

総合スコア12

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/06/11 13:11

C++で,マルチスレッドを用いて以下の問を解くプログラムを教えてください.
マルチスレッドは理論はわかるのですがコーディングの仕方が全然わからなくて困っています.
ネットで調べても無駄に難解なコードしか出てきません. 投げやりかもしれませんが,どなたかにこの問題の解法を解いてほしいです. それを基に勉強したいと思っています...

AさんとBさんの初期位置は自宅で、店にはリンゴが100個あります.
リンゴが完売した時点でプログラムは終了です.
最終的にAさんとBさんはそれぞれ何個のリンゴを購入しましたか?

Aさん
・家からの店への片道時間(帰りも同じ) 1秒
・自宅での荷降ろし 3秒
・八百屋での店員とのやり取り 1秒
・一度に購入できるりんごの個数 5個
Bさん
・家からの店への片道時間(帰りも同じ) 2秒
・自宅での荷降ろし 1秒
・八百屋での店員とのやり取り 2秒
・一度に購入できるりんごの個数 3個
店員
・客は1人ずつしか対応できない
・店にはりんごが100個ある

ちなみに手動で解いたらAさん64個,Bさん36個でした

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

00_x9925

2020/06/11 14:56

まあ,そりゃそういわれますよね.... でしたらマルチスレッドの設計法が分かりやすく説明されているサイトとか,どなたかご存じないですか?
yohhoy

2020/06/11 15:33

マルチスレッド処理プログラミングの難しさの本質は、実装に用いるプログラミング言語に依存しません。 設計法が知りたいとのことでしたら、入門的な「Java言語で学ぶデザインパターン入門 マルチスレッド編」https://www.hyuki.com/dp/dp2.html を紹介しておきます。
guest

回答3

0

ベストアンサー

こんにちは。

terateilがダウンしている間に作っていたら、あららepistemeさんが既に回答されてました。
ま、せっかく作ったので回答します。
素直に待っているとだるいので100倍に加速してます。

C++

1#include <thread> 2#include <mutex> 3#include <atomic> 4#include <chrono> 5#include <algorithm> 6#include <iostream> 7 8void sleep(int sec) 9{ 10 std::this_thread::sleep_for(std::chrono::milliseconds(sec*10)); 11} 12 13int main() 14{ 15 int a=0; 16 int b=0; 17 18 { 19 std::atomic_int apple=100; 20 21 std::mutex mutex; 22 23 // Aさん 24 std::thread therad_a( 25 [&]() 26 { 27 while(0 < apple) 28 { 29 sleep(1); // 店へ向かう 30 { 31 std::lock_guard<std::mutex> lock(mutex); 32 sleep(1); // りんご購入 33 int buy=std::min(5, static_cast<int>(apple)); 34 apple -= buy; 35 a += buy; 36 } 37 sleep(1); // 店から帰る 38 sleep(3); // 荷物を降ろす 39 } 40 }); 41 42 43 // Bさん 44 std::thread therad_b( 45 [&]() 46 { 47 while(0 < apple) 48 { 49 sleep(2); // 店へ向かう 50 { 51 std::lock_guard<std::mutex> lock(mutex); 52 sleep(2); // りんご購入 53 int buy=std::min(3, static_cast<int>(apple)); 54 apple -= buy; 55 b += buy; 56 } 57 sleep(2); // 店から帰る 58 sleep(1); // 荷物を降ろす 59 } 60 }); 61 therad_a.join(); 62 therad_b.join(); 63 } 64 65 std::cout << "a=" << a << "\n"; 66 std::cout << "b=" << b << "\n"; 67}

wandbox

投稿2020/06/11 17:18

編集2020/06/12 09:35
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yohhoy

2020/06/12 00:46

appleは std::atomic<int> にでもしておかないと、(仕様上は)データ競合を起こしますね。
episteme

2020/06/12 05:45

BA横取りされた! www
Chironian

2020/06/12 09:28

yohhoyさん mutexで保護しているつもりががが、while(0 < apple)で漏れてました。 まぁ、ダメな処理系はほとんどないとは思いますが、超嫌なバグ回避のためにはatomic化しておくのが安心ですね。 epistemeさん あうあ。ごめんなさい。
guest

0

リアルタイムにリンゴの買い出しさせてみた。

C++

1#include <iostream> 2#include <future> 3#include <mutex> 4#include <chrono> 5#include <atomic> 6 7int main(void) { 8 using namespace std; 9 using namespace std::chrono; 10 11 mutex mtx; 12 /* 修正: int→atomic<int> 13 read時にmutexで排他してないので。 14 int値のreadは実質atomicに行われるだろうから"まず"大丈夫なんだろけど念のため */ 15 atomic<int> shop_apple = 100; 16 17 future<int> A = async([&]() -> int { 18 int apple = 0; 19 while ( shop_apple > 0 ) { 20 cout << "A 家からの店への片道時間(帰りも同じ) 1秒\n"; this_thread::sleep_for(seconds(1)); 21 mtx.lock(); 22 cout << "A 八百屋での店員とのやり取り 1秒\n"; this_thread::sleep_for(seconds(1)); 23 // 一度に購入できるりんごの個数 5個 24 if ( shop_apple >= 5 ) { 25 apple += 5; 26 shop_apple -= 5; 27 } else { 28 apple += shop_apple; 29 shop_apple = 0; 30 } 31 mtx.unlock(); 32 cout << "A 家からの店への片道時間(帰りも同じ) 1秒\n"; this_thread::sleep_for(seconds(1)); 33 cout << "A 自宅での荷降ろし 3秒\n"; this_thread::sleep_for(seconds(3)); 34 } 35 return apple; 36 }); 37 38 future<int> B = async([&]() -> int { 39 int apple = 0; 40 while (shop_apple > 0) { 41 cout << "B 家からの店への片道時間(帰りも同じ) 2秒\n"; this_thread::sleep_for(seconds(2)); 42 mtx.lock(); 43 cout << "B 八百屋での店員とのやり取り 2秒\n"; this_thread::sleep_for(seconds(2)); 44 // 一度に購入できるりんごの個数 3個 45 if (shop_apple >= 3) { 46 apple += 3; 47 shop_apple -= 3; 48 } else { 49 apple += shop_apple; 50 shop_apple = 0; 51 } 52 mtx.unlock(); 53 cout << "B 家からの店への片道時間(帰りも同じ) 2秒\n"; this_thread::sleep_for(seconds(2)); 54 cout << "B 自宅での荷降ろし 1秒\n"; this_thread::sleep_for(seconds(1)); 55 } 56 return apple; 57 }); 58 59 int A_apple = A.get(); 60 int B_apple = B.get(); 61 cout << endl; 62 cout << "Aさんは " << A_apple << "個のリンゴを買いました\n"; 63 cout << "Bさんは " << B_apple << "個のリンゴを買いました\n"; 64 65}

投稿2020/06/11 16:20

編集2020/06/12 00:58
episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yohhoy

2020/06/12 00:46

shop_apple は std::atomic<int> にでもしておかないと、(仕様上は)データ競合を起こしますね。
episteme

2020/06/12 00:55 編集

えーと...うん、起こしますね仕様上は。 # 修正しておくか...
yohhoy

2020/06/12 03:54

(・∀・)b
guest

0

マルチスレッドを用いて以下の問を解くプログラムを教えてください

このような問題には、マルチスレッドは大げさすぎます。ふつうにシングルスレッドで処理するほうが楽ですし、性能的にも問題ありません。

投稿2020/06/11 14:14

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/06/11 14:22 編集

マルチスレッドを動かすためのコード量もかさむ割に、それを正当化できるだけの理由もないので、「無駄に難解なコード」が出来上がるだけになってしまいます。
00_x9925

2020/06/11 14:57

それはそうなのですが今回はマルチスレッドの勉強がしたいので...
fana

2020/06/12 01:10

マルチスレッドでやると結果が変動し得るような気がしますが(書き方次第か?),そこらへんのことはどうなんでしょう?
dodox86

2020/06/12 03:21

> マルチスレッドでやると結果が変動し得るような気がしますが( 恐らく店員を介したリンゴの在庫の売買操作で、競合が起きらず矛盾も起きないようなフローを実装するのがテーマなのでしょうね。
yohhoy

2020/06/12 07:02 編集

この問題を"解く"場合は、マルチスレッド処理であっても常に計算結果が安定するよう設計・実装する必要がありますね。 そしてそのような設計・実装をするとなると、結局はシングルスレッドで済む処理をただただ複雑に書くだけになるため、maisumakun さん回答に戻ってしまいますw
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問