- ベストアンサー
OSSemCreate関数に引数”1”と入れた場合の動作について
- セマフォを作るためのOSSemCreate関数について質問です。
- 引数に1を入れた場合と0を入れた場合の動作の違いが知りたいです。
- H8S2368マイコンにuCOSというRTOSを組み込んでいるプログラムには、OSSemCreate(1);とOSSemCreate(0);の記述がありますが、使い分けの意味がわかりません。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
ついでなのでかつて紹介したWikipediaの方も読んでください。 OSSemPendはP操作、OSSemPostはV操作に該当します。
その他の回答 (4)
- D-Matsu
- ベストアンサー率45% (1080/2394)
Sw:セマフォを作成、その後P→Vを繰り返す。Pが成功しない場合500msでVを実行 Osc&Osc02:Swで作成したセマフォに対してP、100msの間に成功しなければリトライ というコードでOscとOsc02に優先順位があった場合にどういう動作をしてるのか、という事ですよね。 ぶっちゃけてしまうとスケジューリングポリシー次第としか言いようがありません。 双方がセマフォ待ちをしているときのV操作で通過できるようになるのが必ず優先度の高い方ならOsc02はOscがエラー処理している一瞬でしか通り得ないでしょうし、何らかのポリシーにもとづいて優先度の低い方を処理するかもしれません。 なお優先度が等しい場合、普通は先に待ちに入った方から処理していくはずです。
- R32C
- ベストアンサー率39% (115/290)
おはようございます。 セマフォは、基本は排他制御のための仕組み、さらに単にタスク同期通信の ために使うケースがあります。 貴殿の例示したソースは、後者のタスク間通信を使うケースです。 RTOSもいろいろありますが、考え方は同じ部分も多いです。 VxWorksというRTOSだとタスク同期通信にバイナリセマフォを多様する ことを推奨しています。バイナリセマフォに対する反対のものは計数型セマフォに なります。 おわかりと思いますが、バイナリセマフォは、値は0か1しかとりません。 一方計数型セマフォは、値は0から結構大きな値まで変化できます。 uCOSの場合は計数型ですが、バイナリセマフォとしてももちろん利用できます。 VxWorksでは、バイナリセマフォ専用のシステムコールにして処理を高速化しているようです。 同期通信の場合は、まず0で初期化して、待ちタスクが待ちに入り、割込み等で セマフォをPOST(+1する)ことで起こします。 一方計数型ですが、これは、資源の排他制御用に使います。 変な例えをしますが、 結構大きな飲食店のトイレを考えてみましょう。 男性用 個室3個 (めんどうなので小は省きます) 女性用 個室5個 あったとき、 男性用セマフォは、初期値3、女性用セマフォは、初期値5で初期化します。 利用した場合は、セマフォ獲得(OSSemPend)します。女性なら5人入ったら、6人目は そこで待ち状態になり、先に入った5人のうち一人がでる(OSSemPost)と待っていた先頭の 人が待ち解除になります。 プログラムの中で、タスクで排他制御する場合は、通常資源が1つ、つまり、同時アクセスを 制限するケースで使いますが、資源が複数の場合とは、たとえば、どのポートでもいいのでRS232Cで 通信するというような処理系を 実装したような場合にポート数に応じてセマフォ資源数を定義すればよいことになります。 あと余談ですが、資源の排他制御では、セマフォではpriority inversion(優先順位の逆転) というものが起こるので、これの対策版として、優先度継承機能などのあるミューテックス というシステムコールがあります。μITRONでは、標準機能(スタンダードプロファイルという 機能セット)ではないので、メーカーによっては使えない場合もありますが。
お礼
回答頂きありがとうございました。 わかりやすいたとえを頂きありがとうございました。 >男性用 個室3個 (めんどうなので小は省きます) >女性用 個室5個 いわゆるこの表現が MenBassroom = OSSemCreate(3); WemenBassroom = OSSemCreate(5); この表現に当たるのですね。
- D-Matsu
- ベストアンサー率45% (1080/2394)
書き忘れがありました。 OSSemPend()は呼び出し時に回数が1以上、もしくはスリープ中に1以上になったなら回数を1減らして通過します。
- D-Matsu
- ベストアンサー率45% (1080/2394)
こっちの質問から一年越えましたが、いまだに「セマフォって何なんですか?」状態なのでしょうか。 http://okwave.jp/qa/q4640200.html そこを理解しないといつまでも同じような質問を繰り返すような気がするのですが…… セマフォは内部的に「同時に通過していい回数」を保持していてその回数を増減させることでスレッドの処理を止めたり動かしたりします。 OSSemCreate()の引数は、この回数の初期値を設定しています。 OSSemPend()は、この回数が0の時は1(以上)になるかタイムアウト時間までスレッドの処理を待ちます。 OSSemPost()は、回数を1増加させます。 ですから、OSSemPend()でスリープ(ウェイト)→別スレッドからOSSemPost()でそのスリープを解除、ということができる訳です。
お礼
回答頂きありがとうございます。 確かに、以前私が質問した内容でした。全く記憶から無くなってました。その節はお世話になりました。再度同じ質問となってしまい恐縮です。 この”OSSemCreate()”関数について、”uCOS-II-RefMan.pdf” http://studies.ac.upc.edu/EPSC/SED/Apuntes/uCOS-II-RefMan.pdf このPDFファイルの83ページの”OSSemCreate()”関数に関する英語の説明資料について調べてみたところ、 OS_EVENT *OSSemCreate(INT16U value); • allows a task to synchronize with either an ISR or a task (you initialize the semaphore to 0), • gains exclusive access to a resource (you initialize the semaphore to a value greater than 0), and • signals the occurrence of an event (you initialize the semaphore to 0). Arguments value is the initial value of the semaphore and can be between 0 and 65,535. A value of 0 indicates that a resource is not available or an event has not occurred. Returned Value OSSemCreate() returns a pointer to the event control block allocated to the semaphore. If no event control block is available, OSSemCreate() returns a NULL pointer. Notes/Warnings 1. Semaphores must be created before they are used. このように書かれていたので、yahoo翻訳などで、一応使い方を見てみました。 たぶん、 そのValueに関する英文で ”引数Valueはセマフォの初期値で、0から65,535まで設定することができます。 Valueが0の時は資源(このセマフォのためのにストックしたスタックメモリ領域?)が利用できないことを示します、あるいは、イベントは起こりません。” *かなり自分で勝手に違訳してます。 このValueを0以外の数値にするということはその資源(このセマフォのためのにストックしたスタックメモリ領域?) を使うということだから、引数に”1”を割り当てたら、そのスタックに1個以上のスタックが積まれないと、セマフォを開放(使い方あってますでしょうか?)して、OSSemPendで止まっていたセマフォが通過するようになるということなんでしょうか?
お礼
回答頂きありがとうございます。 wikipediaの”セマフォ”紹介して頂きありがとうございました。 ”OSSemPendはP操作、OSSemPostはV操作に該当します。”というのを踏まえながら読むと実感できました。 ちょっとここで、”OscWait = OSSemCreate(1);”に変更した今回のサンプルプログラムの動作を確認させていただきたいのですが、 今回サンプルプログラムにタスクの優先順位を入れていなかったのですが、 Sw = 1 Osc = 2 Osc02 = 3 このような優先順位を割り振ったとすると、 タスク”Sw”が動作に入り (1)Sw、Osc、Osc02それぞれのタスクが”OSSemPend”に行ってウェイト状態になる。 (2)OscWait = OSSemCreate(1);このプログラムを実行すると、OscWaitセマフォに資源をインクリメントしてスタックされる。(セマフォの資源1) (2)優先順位の高いタスクOscが”OSSemPendでP操作”を行って資源をデクリメントしてエラーなしの動作処理する。(セマフォの資源0) 後にOSSemPend”に行ってウェイト状態。 (3)タスクSwのOSSemPendでのウェイトはタイムアウトエラーで動作処理に入り、OSSemPost(OscWait);でV操作を行いセマフォに資源をインクリメント(セマフォの資源1) (4)再度優先順位の高いタスクOscが”OSSemPendでP操作”を行って資源をデクリメントしてエラーなしの動作処理する。(セマフォの資源0)後にOSSemPend”に行ってウェイト状態。 このような動作を行うと考えてもよいのでしょうか。 こうしてみていくと、一番優先順位の低いタスクOsc02の動作きっかけのタイミングがよくわからないのですが、どのような状況の時にOsc02は動作してくれるのでしょうか?