0

2つのスレッドを作成し、mutexを使用してそれらを同期しました。
もう一方のスレッドが作成されるメインウィンドウプログラム(私はメインスレッドと見なします)では、少なくとも2つの関数でmutexを使用する必要があります。これは、ユーザーがメニューを選択して構成するときにUIからの信号を受け入れるスロットであるためです。データ、および1秒あたり1回実行され、データを読み取るスロット機能をトリガーするタイマーもあります。

mutexを使用していても、プログラムがクラッシュすることがよくあります。「メインスレッド」には、ミューテックスのロックおよびロック解除操作を行うさまざまな機能があります。機能の1つは、タイマーにリンクされたスロットです。また、他のスレッドは継続的にデータを書き込みます

私はとても混乱しています、なぜですか?
(:)この時間の前に質問を編集するにはもっと良い電話が本当に必要です:))

私のコード:
スレッド内:

class Background : public QThread
{
    Q_OBJECT

public:
    void Background::run(void)
    {
        initFile();

        while(1)
        {

            Mutex->lock();
            msleep(40);
            rcv();          //writes map here
            Mutex->unlock();

        }

    }
...
}

スレッドのrcv():

void Background::rcv()
{
    DEVMAP::iterator dev_r;

    for(dev_r= DevMap.begin(); dev_r!= DevMap.end(); dev_r++)//DevMap is a refrence to the dev_map in mainwindow.
    {
       ...  ....//writes the map

    }
}

メインウィンドウ:

void MainWindow::initTimer()
{
    refreshTimer = new QTimer(this);
    connect(refreshTimer, SIGNAL(timeout()), this, SLOT(refreshLogDisplay()));
    refreshTimer->start(1000);
}

void MainWindow::refreshLogDisplay()
{

//MUTEX
    mutex->lock();

    ......//read the map

//MUTEX
    mutex->unlock();

}

スレッドの構成では:

Background(DEVMap& map,...,QMutex* mutex):DevMap(map)...,Mutex(mutex){}

スレッドを作成するメインウィンドウ:

void MainWindow::initThread()
{


    mutex = new QMutex;
    back = new Background(dev_map,..., mutex);
    back->start();

}

と:

void MainWindow::on_Create_triggered()//this function is a slot triggered by a menu item in the MainWindow UI
{

    ......//get information from a dialog 


//MUTEX

    mutex->lock();

    BitState* bitState = new BitState(string((const char *)dlg->getName().toLocal8Bit()),
                                        string((const char *)dlg->getNO().toLocal8Bit()),
                                      dlg->getRevPortNo().toInt(), dlg->getSndPortNo().toInt());


    dev_map.insert(DEVMAP::value_type (string((const char *)dlg->getPIN().toLocal8Bit()), *bitState)); 
     //writes map here



//MUTEX
     mutex->unlock();


}
4

1 に答える 1

2

ミューテックスはどのスレッドでも使用できます。この目的のために設計されました。ただし、たとえば「ロック」の「ネストされた」呼び出しを行う場合は、デッドロックを作成しないでください。

良い:

mutex->lock();
//code
mutex->unlock();
//code
mutex->lock();
//code
mutex->unlock();

悪い:

mutex->lock();
//code
mutex->lock(); //dead lock
//code
mutex->unlock();
//code
mutex->unlock();

関数でロックを使用するときは正確にしてください。

void foo()
{
mutex->lock();
//code
mutex->unlock();
}

mutex->lock();
foo(); //dead lock
mutex->unlock()

また、できるだけ少ないコードをロックする必要があります。sleep()をロック内に配置することは、他のスレッドがスリープ中に待機するため、お勧めできません。

良くない:

while(1)
{
  Mutex->lock();
  msleep(40);
  rcv();
  Mutex->unlock();
}

より良い:

while(1)
{
  msleep(40);
  Mutex->lock();
  rcv();
  Mutex->unlock();
}
于 2012-10-17T11:39:24.007 に答える