0

マルチスレッドを広く使用するシミュレーションに取り組んでいます。問題は、これまでデータを保護するためにミューテックス オブジェクトを使用したことがないということです。その結果、多くのセグメンテーション違反が発生しています..

読み取り/書き込み中にミューテックスでロック/ロック解除しようとしていますが、別のセグメンテーション違反が発生します:

#0 77D27DD2 ntdll!RtlEnumerateGenericTableLikeADirectory() (C:\Windows\system32\ntdll.dll:??)
#1 00000000 ??() (??:??)

もちろん、基本的な状況にロック/ロック解除を適用したテスト プロジェクトを作成し、それが機能しました。GLFW を使用して Mutex オブジェクトを処理する方法を示す基本的な例を次に示します。

#include <GL/glfw.h>
#include <iostream>
#include <vector>

using namespace std;

vector<int> table;
GLFWmutex th_mutex;
void GLFWCALL Thread_1(void* arg) {


    glfwLockMutex(th_mutex);
    table.pop_back();
    glfwUnlockMutex(th_mutex);
}

void GLFWCALL Thread_2(void* arg) {

    glfwLockMutex(th_mutex);
    table.erase(table.begin());
    glfwUnlockMutex(th_mutex);

}

int main()
{

    bool    running = true;
    GLFWthread th_1, th_2;

    glfwInit();

    if( !glfwOpenWindow( 512, 512, 0, 0, 0, 0, 0, 0, GLFW_WINDOW ) )
    {
        glfwTerminate();
        return 0;
    }

    glfwSetWindowTitle("GLFW Application");

    for(int i = 0;i < 10; i++) {
        table.push_back(i);
    }


    th_mutex = glfwCreateMutex();
    th_1 = glfwCreateThread(Thread_1, NULL);
    th_2 = glfwCreateThread(Thread_2, NULL);


    while(running)
    {

        // exit if ESC was pressed or window was closed
        running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam( GLFW_OPENED);
    }

    glfwTerminate();

    return 0;
}

私が取り組んでいるプロジェクトはより大きく、5 つのスレッドが実行されており、多くのベクトル、マップ、キューが同時にアクセスされます。コードのどこかで、次のようなことをしようとしました:

void GLFWCALL CreateVehicleThread(void* arg) {

     int index = (*static_cast<PulseStateByEntrance*>(arg)).index;
     double t_initial = (*static_cast<PulseStateByEntrance*>(arg)).initial_time;
     double t_final = (*static_cast<PulseStateByEntrance*>(arg)).final_time;
     int pulse = (*static_cast<PulseStateByEntrance*>(arg)).pulse;
     int nb_entrance = (*static_cast<PulseStateByEntrance*>(arg)).nb_entrance;
     int min_time_creation = static_cast<int>(ceil(3600 / pulse));


     while((glfwGetTime() - (*static_cast<PulseStateByEntrance*>(arg)).initial_time)
     < ((*static_cast<PulseStateByEntrance*>(arg)).final_time - (*static_cast<PulseStateByEntrance*>(arg)).initial_time)) {


           double t_elapsed = glfwGetTime() - t_initial;


           if(t_elapsed > min_time_creation) {

                 **int nb_vehicle_per_cycle = static_cast<int>((t_elapsed * pulse)/3600);
                 glfwLockMutex(th_mutex);
                 VehicleManager::CreateVehicles(nb_vehicle_per_cycle, nb_entrance);
                 glfwUnlockMutex(th_mutex);**
                 t_initial = glfwGetTime();

           }

    }


}

VehicleManager:CreateVehicles() メソッドをロック/ロック解除の間に配置する理由は、このメソッドに次の行があるためです。

VehicleManager::vehicles_.push_back(vehicle);

だから私はベクトルを保護したかった: vehicle_. しかし、結果として、上記のセグメンテーション違反が発生しました。そしてでも:

glfwLockMutex(th_mutex);
VehicleManager::vechicles_.push_back(vehicle);
glfwUnlockMutex(th_mutex);

私は同じセグメンテーション違反を起こしました。

あなたが私の問題の性質を理解できるように、私は自分自身を十分に明確にしたことを願っています. 皆さん全員が GLFW を使用したことがあるわけではないので、このライブラリでミューテックスがどのように機能するかを理解できるように、最初の基本的な例を示しました。

ありがとう !

4

2 に答える 2

1

コードを理解しやすくするコンテナをラップできます。

template<typename T>
class MultithreadedVector
{
public:
    void pushback( T data )
    {
        glfwLockMutex(m_mutex);
        m_container.push_back( data );
        glfwUnlockMutex(m_mutex);
    }
//then similar for erase etc
private:
    std::vector<T> m_container;
    GLFWmutex m_mutex;
};
于 2009-06-15T19:28:01.707 に答える