重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

Linux初心者です。
2.6-18-at9 Debianで及ばずながらマルチスレッドのプログラムを書いています。

VBにはOSにコントロールを戻すDoEventsという機能があります。
Windows/VC++ではこれと同等機能の関数を使っています:

DWORD DoEvents(VOID)
{
MSG msg;
while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ){
if ( msg.message == WM_QUIT ){
return( msg.message );
}
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return( 0 );
}

どなたかの示唆によるもので内容はよく理解していませんが、Windows下ではこれで長年つかえてきました。
Linux-gccで同等の関数は定義できるのでしょうか?。

A 回答 (2件)

PthreadsならPthreadクラスのsleepメソッドを用いてはどうでしょう。


http://www5a.biglobe.ne.jp/~mick/contents/progra …
    • good
    • 0
この回答へのお礼

nora1962様

回答ありがとうございます。

PCからのデータ(data)を受信専用スレッドで受信、メインスレッドで

data = 0;
while (!data) sleep(1);
printf(data %x\n, data);

によりPCからのデータを取得できました。
sleep(1);は特に準備不要で使えました。

VC++におけるSleepでは同じことはできず、先に挙げたDoEvents()を使わざるを得なかったと記憶しています。

ありがとうございました。

お礼日時:2011/03/11 20:46

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;
}
    • good
    • 0
この回答へのお礼

svgh様

回答ありがとうございます。
DoEventsの内容を理解せず、やみくもに使っていました。

当面の課題はsleep(1)で済み、これで先に進むことにしましたが、提示していただいたコードを解釈、DebianのAPIを調べてトレースしてみます。

勉強になりました。ありがとうございました。

お礼日時:2011/03/11 20:55

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!