セマフォとスレッドの問題について

このQ&Aのポイント
  • セマフォとスレッドの問題に関して東京大学大学院の問題なのですが、解き方がわからない
  • 8つのスレッドがあり、それぞれのスレッドはセマフォを使用して同期制御を行う必要がある
  • ステートメント間の依存性がある場合、それぞれのスレッドがどのように同期するか説明せよ
回答を見る
  • ベストアンサー

セマフォとスレッドの問題について

この問題は東京大学大学院の問題なのですが、問題の求めているものがよくわかりません。 セマフォとスレッドなどは勉強して理解しているのですがこの問題はどのようにして解くのでしょうか? 8つのスレッドT1,T2,・・・,T8がある。それぞれのスレッドTiはステートメントSi()を実行するが、Sj()に関連付けされたセマフォSjのオペレーションP(Sj),V(Sj)などを利用して同期・排他制御を行う。(i,j=1,・・・,8)。ステートメントSi間の実行順序に添付した図のような依存性がある場合、それぞれのスレッドTiが実装する同期方法をSi(),P(Sj),V(Sj)などを用いて説明せよ(i,j=1,・・・,8)。 例えば、S1()はS2()とS3()より前に実行する必要があるが、S2()とS3()は同時実行可能である。また、S7()はS4()とS5()が終了しないと実行できない。全てのセマフォは初期化されていると仮定してよい。

質問者が選んだベストアンサー

  • ベストアンサー
noname#134443
noname#134443
回答No.1

初めて回答する者です。よろしくお願いします。 最初にS1ですべてのロックを獲得(P操作)し、 そのあと、S2~S8のスレッドを起動します。 (それぞれのスレッドはロックが解放されるまで待機します。) 最後にS1のロックを解放(V操作)します。 関数S1() { P(S1) P(S2) P(S3) P(S4) P(S5) P(S6) P(S7) P(S8) //スレッド起動し、待機。 S2() S3() S4() S5() S6() S7() S8() //S1処理が終了したことをロックの解放によって知らせる。 V(S1) } S1の処理が終わるまでP(S1)にて待ちます。 S1の処理がV(S1)にて終われば次の処理(S2の処理)が進んでいきます。 それぞれのスレッド処理の終わりにロックを解放します。 関数S2() { P(S1) V(S1) V(S2) } 同様に考えていきます。 関数S3() { P(S1) V(S1) V(S3) } 関数(S4) { P(S2) V(S2) V(S4) } 関数(S5) { P(S3) V(S3) V(S5) } 関数(S6) { P(S3) V(S3) V(S6) } 関数(S7) { P(S4) V(S4) P(S5) V(S5) V(S7) } 関数(S8) { P(S6) V(S6) P(S7) V(S7) V(S8) } こんな感じでしょうか。

関連するQ&A

  • OSで、、、、、、セマフォと、モニタ、

    について説明してください、セマフォのP操作例えは資源を一個とってくることを 言って、V操作は資源を返して下さい、っていうようなことでしょうか? 多分そうだと思うのですが、、、あとセマフォ変数Sっていうのが資源の 数ですよね?これであってますよね? 教科書よんでてあれ?って思いましたから あとモニタは具体的にわかりやすく言うとなんですか?なんか共有資源が どうのこうの、、、、、共有資源ってCPUとかですよね? 実世界では電卓とか鉛筆削りとかですよね~? それでは、

  • 【C++】セマフォとプロセスの使い方

    【C++】セマフォとプロセスの使い方 WindowsXPでVC++2008コンパイラを使用して、 プロセスとセマフォについて勉強しています。 外部プログラム(今回は電卓として)を5つ立ち上げるのですが、 同時に立ち上げるのは2つまでとしたい場合、どのように組むのでしょうか。 http://nienie.com/~masapico/api_CreateSemaphore.html こちらにスレッドを使用したセマフォを使ったサンプルがあるのでが、 プロセスを使うとなると、うまく書けません。 ご指導頂けませんでしょうか。 ===現在まで書いたソース=== (5つのプロセスをつくるループも実装していませんが、、、) #include<windows.h> #include<stdio.h> #include<tchar.h> HANDLE g_hSemaphre; void main(){ BOOL bRet; STARTUPINFO si; PROCESS_INFORMATION pi; //Semaphoreオブジェクト g_hSemaphre = CreateSemaphore(NULL,2,2,NULL); bRet = CreateProcess(_T("C:\\WINDOWS\\system32\\calc.exe"), _T(""), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); //プロセス終了 WaitForSingleObject(pi.hProcess,INFINITE); //後処理(プロセス開放) ReleaseSemaphore(g_hSemaphre,1,NULL); //スレッドとプロセスを閉じる。 CloseHandle(pi.hThread); CloseHandle(pi.hProcess); //Semaphoreオブジェクト CloseHandle(g_hSemaphre); }

  • スレッドの優先順位に関して

    ただ今、黒本(徹底攻略 Java2 プログラマ問題集 Platform5.0 対応) を使用しSJC-Pの勉強をしているんですが、スレッドの20番目の問題が どうしてもわからないので質問させて下さい。 下記の問題なんですが コンパイルし実行した結果として正しい物を選ぶという 問題で、答えは「 B A B A B A と表示される」になります。 class MyThread extends Thread{ MyThread(String name){ super(name); } public void run(){ System.out.println(getName()); for(int i=0;i<2;i++){ try{ sleep(1000); }catch(Exception e){} yield(); System.out.println(getName()); }}} class T20{ public static void main(String[] args){ Thread t1 = new MyThread("A"); t1.setPriority(1); t1.start(); Thread t2 = new MyThread("B"); t2.setPriority(10); t2.start(); } } この問題の答えの解説で 優先順位を指定すると必ず高い優先順位のスレッドから 実行が開始するみたいな事が書かれてて、おかしいと思い、 検証してみたところ、私の環境では、結果が何通りも表示されました。 yield()についても私の持っている別の参考書には 「現在実行中のスレッドオブジェクトを実行可能状態に戻し、 他のスレッドに実行できるようにする。ただし優先順位の関係で実行中だったスレッドが再度実行される可能性もある。」 と書かれていて上記の答えに納得が出来ていません。 スレッドの優先順位とyieldに関して お手数ですが、アドバイスよろしくお願いします。

    • ベストアンサー
    • Java
  • アトミック・オペレーションについて

    私は情報科学科に在籍している大学生です。 いま排他制御やセマフォを勉強しているのですが、その関係で下記のようなことも勉強しています。 アトミック・オペレーションはセマフォみたいなP()やV()のようなものでしょうか? ぜひ教えていただければ幸いです。 よろしくお願いします。 (1)アトミック・オペレーションを簡単に定義せよ。 (2)2つのスレッドT1とT2がそれぞれアトミック・オペレーションa、b、c、d、eを下記のように実行する場合、全ての可能な実行順序を記せ。 ・T1 : {a,b,c} ・T2 : {d,e}

  • 数学の濃度の問題

    どなたか、よろしくお願いいたします。 (1),|N*N|=|N| NからN*Nへ全単射の関数を規定したいです。 N*N=(m,n){m,n∈N} (2), N^k={(n1,n2,,nk)|ni∈N,1≦i≦k} |N^k|=|N|(帰納法を用いて) a), K=1 のとき、|N|=|N|であり、明らか。 b), K=m で成り立っているとき、K=m+1でも題意が成り立つことを示す。 T={N^m}S={N} |N^m|=|N| つまりこれは、f:S→T 全単射である。Si=Ti N^(m+1)はN・Ti これは、f:N→N^(m+1) g=N*f 関数gで表わせれる。 もし、Si=Ti であれば gf(si)=N*Si=gf(ti)=N*Tiであり。これは全単射である。 雑すぎて自分でもよくわかっていません。。 (3)S={1,2,3,4.....,10^6} Tを全てのSの部分集合とする。f:T→Sを満たす、 1対1のfが存在しないことを示せ。

  • プログラムのスレッド化について。

    以下の処理をスレッド化しようとしています。 public class FCP{ int N=10 long LOOP_MAX=100 double x[][] = new double[N][4] int g[][] = new int[N][4] boolean y[][] = new boolean[N][4]//出力 boolean A[][] = new boolean[N][10] double T=0.5 Set_Adjacent_Matrix() //A配列にtrueとfalseを代入 Set_initial_value() //y配列に初期値を代入(Math.random()>0.5) g1(int i, int j) //k<4 sum=1 if( y[i][k] == true ) --sum return(double)sum g2(int i, int j) //k<N sum=0 if( y[i][j] == true ) if( y[k][j] == true && A[i][k] == true ) --sum return(double)sum Display_output() //結果表示 if( y[i][j] ) System.out.print("0") else System.out.print(".") public static void main(String args[]) { long loop; int i, j, k; Set_Adjacent_Matrix(); Set_initial_value(); for( loop=0; loop<LOOP_MAX; loop++ ){ for( i=0; i<N; i++ ){ for( j=0; j<4; j++ ){ x[i][j] = g1( i, j ) + g2( i, j ); if( y[i][j] ){ x[i][j] += T; }else{ x[i][j] -= T; } if( x[i][j] > 0.0){ y[i][j] = true; }else{ y[i][j] = false; } } } Display_output(); } } 今回Threadクラスの継承を使ってスレッド化しようと考えました。runメソッドには上のプログラムのmain部分の処理をさせようと思っています。そしてstartメソッドで必要な数(Nの値=10コ)のスレッドを生成しrunメソッドを実行する。 と、ここまではわかったのですが、「生成された各スレッドの番号を保持し、そのスレッドに担当させる処理を決める」という部分をどうすればいいのかわかりません。 「i(1~10)番目のスレッドはN(1~10)列目の処理を担当している」という風にするにはどうしたらいいのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • 物理の問題ですが教えて下さい。

    物理の問題なのですが。教えて下さい。 このような問題がでたのですが、答えは合ってますでしょうか? このようなことも書いてありました。 消費した電力 =パワー×時間 =P×t =I・V×t I・V×t =RI^2×t から以下を答えよ。 I= R= V= t= (1時間は3600秒) 私が考えた答え I=V・t R=I^2・t V=I・t t=3.6×10^6J 明日テストなのです。よろしくお願いします。

  • スレッドの状態遷移について。。。

    Javaの本を買って読んでいます。 その中の「スレッド」のカテゴリーの「状態遷移」のところの「synchronized」の部分に、こう書かれています。 -------------------------- ・・・・・・ なお、sleepメソッドでスリープ状態(実行不可能状態)になったスレッドはロックを保持したまま開放しません。 そのため、ロックを取得できないで待たされるスレッドも実行不可能状態へ移行させられます。 -------------------------- これは、Synchronized指定されたメソッド(同期メソッド)の部分で出てきた文章でして、 私は、こう解釈しました。 → 例えば、同じオブジェクトの参照を引数とするスレッドが3つあり、その中の1つが『実行中』状態にある(仮に t1 とする)として(つまり残り2つ( t2 t3 )は『実行可能状態(プール)』にある。)、 実行中の t1 がsleep()メソッドで『実行不可能状態』になった場合、 『実行可能状態』にあった、t2 t3 も『実行不可能状態』へ移行する事になる。 間違っていますか? もし、この解釈が正しければ、こうなりますよね? t1・・・・・・・『実行中』 → 『実行不可能状態』 t2 t3・・・『実行可能状態』 → 『実行不可能状態』 ところが、状態遷移の5つの状態の図を見ると、 『実行可能状態』 から 『実行不可能状態』 へは、矢印→が書かれておりません。(逆向きの矢印がありますが。) どういう意味でしょうか。 java初心者ですが、 解りやすく教えて頂けると助かります。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • スレッド

    VC++2008ExpressEditionを使用してプログラムを作成しています。 Windowsフォームアプリケーションを作成し、そこに、TextBoxとButtonを放り込み、ボタンを押すと以下のようなコードが実行されるようにしました。 関数testfuncはhoge::Form1::testfuncという風な場所で定義されています。 logBoxは、Form1のコンストラクタのTODOの部分で作成しています。   public: static System::Windows::Forms::TextBox^ logBox;   void testfunc(){     int i;     for(i=0;i<200;i++){       int t=clock();       while(10>clock()-t);       logBox+=L"aaraeaewa"+i+L"\r\n";       logBox->SelectionStart = logBox->Text->Length;       logBox->ScrollToCaret();     }   }   System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {     button1->Enabled=false;     button1->Text=L"実行中";     button1->Update();     ThreadStart^ trddel=gcnew ThreadStart(this,&hoge::Form1::testfunc);     Thread ^trd=gcnew Thread(trddel);     trd->Start();     button1->Enabled=true;     button1->Text=L"実行";   } この関数をボタンを押して実行すると、testfunc関数の logBox->SelectionStart = logBox->Text->Length; の部分で、 'System.InvalidOperationException' のハンドルされていない例外が System.Windows.Forms.dll で発生しました。 追加情報: 有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール 'logBox' がアクセスされました。 という風なエラーが出ます。 読んだ感じだと、元々のスレッドで作成したコントロールを新しく作ったスレッドからコントロールすることは出来ないって感じのことが書かれているのですが、どの様にすればこれは回避できるようになるのでしょうか?

  • 階段行列の定義

    本にm×n行列Aが階段行列であるとは、A=Oであるか 次の条件を満たす時をいう(ここからがわかりません) 1≦s1≦s2≦、、、≦st≦nなるs1、s2、、、stが存在して、(ここでtとは1≦t≦mなる数である) (1)各si、1≦i≦t列はm次基本ベクトルeiである (2)j<s1なる各j列は零ベクトルである (3)各1≦i≦tにおいてsi≦j≦si+1(i=tのときはst<j<≦n)なる各j列はj+1成分以下はすべて0である。 1≦s1≦s2≦、、、≦st≦nなるs1、s2、、、stが存在して、(ここでtとは1≦t≦mなる数である) という部分について、s1s2、、、というのは何ですか?ただの数とするとおかしいです (1)から(3)の意味についておしえてください。