Ich arbeite an einer Simulation, die Multithreading ausgiebig verwendet. Die Sache ist, dass ich bis jetzt noch keine Mutex-Objekte benutzt habe, um meine Daten zu schützen. Und das Ergebnis ist, dass ich Bündel von Segmentation Faults bin immer ..C++/GLFW - Der richtige Weg, um Mutex-Objekte zu verwenden?
Ich versuche, mit Mutex zum Sperren/Entsperren während: Lesen/Schreiben, aber das macht mir ein anderes segfault:
#0 77D27DD2 ntdll!RtlEnumerateGenericTableLikeADirectory() (C:\Windows\system32\ntdll.dll:??)
#1 00000000 ??() (??:??)
Of natürlich habe ich ein Testprojekt erstellt, wo ich das Sperren/Entsperren, was für eine grundlegende Situation angewandt und es hat funktioniert, hier ist ein einfaches Beispiel, das zeigt, wie mit Mutex-Objekten behandeln GLFW mit:
#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;
}
Das Projekt, i arbeite ich ist größer, ich habe 5 Threads darauf laufen, und eine Menge von Vektoren, Karten, q auf sie wird gleichzeitig zugegriffen. Irgendwo im Code, habe ich versucht, so etwas wie zu tun:
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();
}
}
}
Der Grund, warum, ich stelle meine VehicleManager: CreateVehicles() -Methode zwischen Sperren/Entsperren ist, weil bei diesem Verfahren gibt diese Zeile:
VehicleManager::vehicles_.push_back(vehicle);
So wollte ich den Vektor schützen: vehicles_. Aber als Ergebnis habe ich diesen segfault oben. Und sogar mit:
glfwLockMutex(th_mutex);
VehicleManager::vechicles_.push_back(vehicle);
glfwUnlockMutex(th_mutex);
ich bekam den gleichen segfault.
Ich hoffe, ich habe mich selbst klar genug gemacht, dass Sie die Natur meines Problems verstehen. Ich nehme an, nicht alle von Ihnen haben mit GLFW gearbeitet, deshalb habe ich Ihnen das erste grundlegende Beispiel gegeben, damit Sie verstehen können, wie Mutexe mit dieser Bibliothek arbeiten.
Danke!
Ich finde es elegant, werde es versuchen! Vielen Dank ! –