- ベストアンサー
LinuxでDoEvents()同等機能
- Linux初心者です。2.6-18-at9 Debianで及ばずながらマルチスレッドのプログラムを書いています。
- VBにはOSにコントロールを戻すDoEventsという機能があります。Windows/VC++ではこれと同等機能の関数を使っています。
- どなたかの示唆によるもので内容はよく理解していませんが、Windows下ではこれで長年つかえてきました。Linux-gccで同等の関数は定義できるのでしょうか?。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
PthreadsならPthreadクラスのsleepメソッドを用いてはどうでしょう。 http://www5a.biglobe.ne.jp/~mick/contents/program/pthread.html
その他の回答 (1)
- sygh
- ベストアンサー率76% (42/55)
WindowsのDoEventsは、GUIプログラムにおいて、メッセージ ループを持つメイン スレッド(UIスレッド)上で実行するべき処理であって、サブ スレッド(ワーカー スレッド)から呼び出してよいものではありません。 DoEventsは主にシングル スレッドのGUIプログラムにおいて、長時間かかる処理を実行している最中に、ユーザーによる中断指示の検出をする場合などに使われます。 マルチ スレッド プログラムにおいては、そもそもメイン スレッドでは長時間かかる処理を行なわないのが原則です。サブ スレッドとの通信や同期は、メッセージ キューやイベントなどの同期オブジェクト、スレッド間共有メモリなどを介して行ないます。 DebianのネイティブAPIは分かりませんが、Qtの場合、QCoreApplication::processEvents()がDoEventsに相当します。 http://qt.nokia.com/downloads-jp/ 下記はQtのサンプル コードです。 // 宣言ファイル。 #ifndef WIDGET_H #define WIDGET_H #include <QWidget> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private: Ui::Widget *ui; bool isStopped; private slots: void on_btnStop_clicked(); void on_btnStart_clicked(); }; #endif // WIDGET_H // 実装ファイル。 #include "widget.h" #include "ui_widget.h" #include <qthread.h> class ThreadSleeper : public QThread { public: static void sleep(unsigned long secs) { QThread::currentThread()->sleep(secs); } static void msleep(unsigned long msecs) { QThread::currentThread()->msleep(msecs); } static void usleep(unsigned long usecs) { QThread::currentThread()->usleep(usecs); } }; Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget), isStopped() { ui->setupUi(this); ui->progressBar->setValue(0); } Widget::~Widget() { delete ui; } void Widget::on_btnStart_clicked() { ui->btnStart->setEnabled(false); this->isStopped = false; ui->progressBar->setValue(0); do { for (int i = 0; i < 10; ++i) { ThreadSleeper::msleep(100); qApp->processEvents(); } ui->progressBar->setValue(ui->progressBar->value() + 10); } while (ui->progressBar->value() < ui->progressBar->maximum() && !this->isStopped); ui->btnStart->setEnabled(true); } void Widget::on_btnStop_clicked() { this->isStopped = true; }
お礼
svgh様 回答ありがとうございます。 DoEventsの内容を理解せず、やみくもに使っていました。 当面の課題はsleep(1)で済み、これで先に進むことにしましたが、提示していただいたコードを解釈、DebianのAPIを調べてトレースしてみます。 勉強になりました。ありがとうございました。
お礼
nora1962様 回答ありがとうございます。 PCからのデータ(data)を受信専用スレッドで受信、メインスレッドで data = 0; while (!data) sleep(1); printf(data %x\n, data); によりPCからのデータを取得できました。 sleep(1);は特に準備不要で使えました。 VC++におけるSleepでは同じことはできず、先に挙げたDoEvents()を使わざるを得なかったと記憶しています。 ありがとうございました。