この記事は2018年08月09日に投稿しました。
目次

世界でいちばん簡単なVisualC++のe本 標準C++とC++/CLIの基本と考え方がわかる本
- 作者: 金城俊哉
- 出版社/メーカー: 秀和システム
- 発売日: 2009/10/26
- メディア: 単行本
- 購入: 2人 クリック: 26回
- この商品を含むブログ (2件) を見る
1. はじめに
こんにちは、iOSのエディタアプリPWEditorの開発者の二俣です。
今回は業務で使用しているC++/CLIの話です。
シリアル通信を行うアプリで、シリアル通信処理部分と上位(GUI)処理で受信コマンドの受け渡しに排他制御したキューを使用しました。
その時使用した排他制御したキューの実装例です。
2. 排他制御したキュー
排他制御したキューは、
- キューQueueオブジェクト
- イベントManualResetEventオブジェクト
- モニターMonitorオブジェクト
を使用して実装しました。
処理の概要ですが、
- キューQueueオブジェクトに受信コマンド(文字列)をキューイングします。
- キューQueueオブジェクトに受信コマンドを設定する/取り出す時、モニターMonitorオブジェクトで排他ロックします。
- 取り出す側は、イベントManualResetEventオブジェクトでイベント待ちします。 設定する側は、設定した時にイベントを発生させ、取り出し側に受信コマンドが設定されたことを通知します。
となります。
以下が使用する手順です。
- 上位(GUI)のコマンド待ち処理の中で、WaitMsgメソッドを呼び出し、シリアル通信処理からコマンドが受信されるのを待ちます。
- シリアル通信処理でコマンドを受信したとき、SetMsgメソッドでキューにコマンドをセットします。
- 2のSetMsgメソッドが呼び出されると、WaitMsgメソッドの待ち状態が解除されます。
キューに積まれたコマンドを取得して、コマンドに応じた処理を行います。
namespace Util { using namespace System; using namespace System::Collections; using namespace System::Threading; ref class QueueUtil { private: /// 自クラスのインスタンス static QueueUtil^ instance; /// キューオブジェクト Queue^ queue; /// イベントオブジェクト ManualResetEvent^ event; /// <summary> /// コンストラクタ /// /// param capacity: キューイングするメッセージの数 /// </summary> QueueUtil(int capacity) { queue = gcnew Queue(capacity); queue->Clear(); event = gcnew ManualResetEvent(false); } public: /// <summary> /// インスタンスを返却します。 /// /// param capacity: キューイングするメッセージの数 /// </summary> static QueueUtil^ GetInstance(int capacity) { // インスタンスが未精製の場合 if (instance == nullptr) { // インスタンスを生成します。 instance = gcnew QueueUtil(capacity); } return instance; } /// <summary> /// メッセージをキューに設定します。 /// /// param msg: メッセージ /// </summary> void SetMsg(String^ msg) { // イベントとキューが有効な場合 // 念のためのチェック if ((event != nullptr) && (queue != nullptr)) { // キューをロックします。 Monitor::Enter(queue); // キューにメッセージを設定します。 queue->Enqueue(msg); // イベントをセットします。 event->Set(); // キューのロックを解除します。 Monitor::Exit(queue); } } /// <summary> /// メッセージがキューに設定されるのを待ちます。 /// /// return: メッセージ /// </summary> String^ WaitMsg() { // イベント待ち。 event->WaitOne(); // キューをロックします。 Monitor::Enter(queue); // キューにメッセージが設定されている場合 String^ msg = String::Empty; if (queue->Count > 0) { // キューからメッセージを取得します。 msg = (String^)(queue->Dequeue()); // キュー設定されたメッセージ分処理するため、 // キューが空になってからイベント待ち状態にします。 if (queue->Count == 0) { // イベント待ち状態に設定します。 event->Reset(); } } // キューにメッセージが設定されていない場合 // 念のための処理 else { // イベント待ち状態に設定します。 event->Reset(); } // キューのロックを解除します。 Monitor::Exit(queue); return msg; } }; }
API Reference
Queueクラス
ManualResetEventクラス
Monitorクラス
3. おわりに
例によって、C++/CLIに詳しい同僚に教えてもらいました。
こういったロジックを覚えるのはいつも楽しいです。
知識・スキルの販売サイト【ココナラ】

Visual C++ 2005 実用サンプルプログラム WindowsプログラミングTips108
- 作者: 松浦健一郎,司ゆき
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2007/11/15
- メディア: 大型本
- クリック: 3回
- この商品を含むブログ (3件) を見る
紹介している一部の記事のコードはGitlabで公開しています。
興味のある方は覗いてみてください。
私が勤務しているニューラルでは、主に組み込み系ソフトの開発を行っております。
弊社製品のハイブリッドOS Bi-OSは高い技術力を評価されており、特に制御系や通信系を得意としています。
私自身はiOSモバイルアプリやウィンドウズアプリを得意としております。
ソフトウェア開発に関して相談などございましたら、お気軽にご連絡ください。
また一緒に働きたい技術者の方も随時募集中です。
興味がありましたらご連絡ください。
EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688