Hackerboard Wiki HaboBlog
Hackerboard bei Facebook Hackerboard bei Google+ Hackerboard bei Twitter

[HaBo]

 
Code Kitchen Allgemeines Coder-Forum rund um das Programmieren eigenständiger, ausführbarer Programme.

[gelöst] Mutex nach Initialisierung gelockt!?

Diskussion: [gelöst] Mutex nach Initialisierung gelockt!? im Forum Code Kitchen, in der Kategorie Software Home; Anzeige Moin, Moin! Ich schlage mich hier gerade mit einem Multithreadingproblem herum und sehe den Fehler einfach nicht. Meine Applikation ...

Antwort
Alt 16.12.11, 10:40   #1 (permalink)
 
Registriert seit: 06.06.09
Thunderb0lt Leistung: 8086
Likes: 6
erledigt [gelöst] Mutex nach Initialisierung gelockt!?

Anzeige

Moin, Moin!

Ich schlage mich hier gerade mit einem Multithreadingproblem herum und sehe den Fehler einfach nicht. Meine Applikation erstellt an einem Punkt einen neuen Thread, um GPS Informationen zu empfangen. In der Hauptapplikation werden die empfangenen Positionen dann zwischen durch immer mal wieder abgefragt. Ich habe die Datenstruktur, die die Positionen speichert deshalb mit einem Mutex geschützt. Das Problem ist nur, dass bereits der erste Aufruf um den Mutex zu sperren blockiert bzw. den Fehler schmeißt, der Mutex sei bereits gesperrt. Irgendwo muss in meinem Programm also ein Fehler sein, aber ich finde ihn einfach nicht. Sieht vielleicht einer von euch, wo das Problem liegt?

Code:
void Executor::startReceivingGPSData()
{
    gpsInfos = new GPSMoveCommand::VehicleInfos();

    gpsReceiverThread = new pthread_t;
    int err = pthread_create( gpsReceiverThread, NULL, Executor::gpsReceivingFunc, &gpsInfos);
    if(err)
    {
        logger << "GPS receiving thread: pthread_create() failed with error code: " << err
               << " " << strerror(err);
    }
}
Code:
/* static */ void * Executor::gpsReceivingFunc( void * result )
{
    logger << "GPS receiving thread started";

    GPSMoveCommand::VehicleInfos * const vehicleInfos = reinterpret_cast<GPSMoveCommand::VehicleInfos * const>(result);

    Receiver & receiver = Receiver::getInstance();
    receiver.startReceive( vehicleInfos );

    return NULL;
}
Code:
class GPSMoveCommand
{

public:

  struct VehicleInfos
  {
      typedef std::map<int, double> vehicleInfo;
      typedef std::map<unsigned int, vehicleInfo> vehicleInfoList;
      
      VehicleInfos()
      {
          pthread_mutexattr_t attr;
          pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);

          int err = pthread_mutex_init( &mutex, &attr );
          if( err )
          {
              logger << "Failed to init mutex: "
                     << strerror(err);
          }
      };

      double getLongByVehicle( const unsigned int vehicleID )
      {
          if( vehicles.end() == vehicles.find(vehicleID) )
          {
              logger << "Got Request for GPS information for non-existing vehicleId=" << vehicleID;

              return 0;
          }

          int err = pthread_mutex_trylock( &mutex );
          if( err )
          {
              logger << "Failed to lock mutex: "
                     << strerror(err);

              return 0;
          }

          const double longitudeDeg = vehicles[vehicleID].at(longitude);

          err = pthread_mutex_unlock( &mutex );
          if( err )
          {
              logger << "Failed to unlock mutex: "
                     << strerror(err);
          }

          return longitudeDeg;
      };

      double getLatByVehicle( const unsigned int vehicleID )
      {
          if( vehicles.end() == vehicles.find(vehicleID) )
          {
              logger << "Got Request for GPS information for non-existing vehicleId=" << vehicleID;

              return 0;
          }

          int err = pthread_mutex_trylock( &mutex );
          if( err )
          {
              logger << "Failed to lock mutex: "
                     << strerror(err);

              return 0;
          }

          const double latitudeDeg = vehicles[vehicleID].at(latitude);

          err = pthread_mutex_unlock( &mutex );
          if( err )
          {
              logger << "Failed to unlock mutex: "
                     << strerror(err);
          }

          return latitudeDeg;
      };

      double getVelocityByVehicle( const unsigned int vehicleID )
      {
          if( vehicles.end() == vehicles.find(vehicleID) )
          {
              logger << "Got Request for GPS information for non-existing vehicleId=" << vehicleID;

              return 0;
          }

          int err = pthread_mutex_trylock( &mutex );
          if( err )
          {
              logger << "Failed to lock mutex: "
                     << strerror(err);

              return 0;
          }

          const double velocityMPS = vehicles[vehicleID].at(velocity);

          err = pthread_mutex_unlock( &mutex );
          if( err )
          {
              logger << "Failed to unlock mutex: "
                     << strerror(err);
          }

          return velocityMPS;
      };

      void setLongByVehicle( const unsigned int vehicleID, const double value )
      {
          int err = pthread_mutex_trylock( &mutex );
          if( err )
          {
              logger << "Failed to lock mutex: "
                     << strerror(err);

              return;
          }

          vehicles[vehicleID][longitude] = value;

          err = pthread_mutex_unlock( &mutex );
          if( err )
          {
              logger << "Failed to unlock mutex: "
                     << strerror(err);
          }
      };

      void setLatByVehicle( const unsigned int vehicleID, const double value )
      {
          int err = pthread_mutex_trylock( &mutex );
          if( err )
          {
              logger << "Failed to lock mutex: "
                     << strerror(err);

              return;
          }

          vehicles[vehicleID][latitude] = value;

          err = pthread_mutex_unlock( &mutex );
          if( err )
          {
              logger << "Failed to unlock mutex: "
                     << strerror(err);
          }
      };

      void setVelocityByVehicle( const unsigned int vehicleID, const double value )
      {
          int err = pthread_mutex_trylock( &mutex );
          if( err )
          {
              logger << "Failed to lock mutex: "
                     << strerror(err);

              return;
          }

          vehicles[vehicleID][velocity] = value;

          err = pthread_mutex_unlock( &mutex );
          if( err )
          {
              logger << "Failed to unlock mutex: "
                     << strerror(err);
          }
      };

      private:
          enum infos {
              latitude = 0,
              longitude,
              velocity
          };

      vehicleInfoList vehicles;
      pthread_mutex_t mutex;
  };
  
  //...
  
};
__________________
A good programmer looks both ways before crossing a one-way street.

Die Politik kann uns nur für so dumm verkaufen, wie wir sind.

Geändert von Thunderb0lt (21.12.11 um 18:39 Uhr) Grund: Problem gelöst
Thunderb0lt ist offline   Mit Zitat antworten
Alt 16.12.11, 12:39   #2 (permalink)
 
Benutzerbild von blue182
 
Registriert seit: 21.08.10
blue182 Leistung: Facit NTK
Likes: 10
Standard

Ich bin jetzt grad etwas zu faul den gesamten Quellcode zu lesen, aber wie initialisierst du die Lock?

Schau dir vielleicht mal eine Semaphore an, die du mit einem Platz initialisierst, dadurch erzielst du nichts anderes, als ein Mutex.


Hier etwas Quellcode, sehr spartanisch, aber überschaubar
Code:
#ifndef CMUTEX_H_
#define CMUTEX_H_


#include <semaphore.h>
#include <errno.h>

class CMutex {
public:
    CMutex();
    ~CMutex();

    void lock();
    void unlock();
    bool tryLock();

private:
    sem_t _sem;

};

#endif /* CMUTEX_H_ */

#include "CMutex.h"

CMutex::CMutex() {
    sem_init(&_sem, 0, 1);
}

CMutex::~CMutex() {
    sem_destroy(&_sem);
}

void CMutex::lock() {
    sem_wait(&_sem);
}

void CMutex::unlock() {
    sem_post(&_sem);
}

bool CMutex::tryLock() {
    if (sem_trywait(&_sem) == EAGAIN
        )
        return false;
    return true;
}
blue182 ist offline   Mit Zitat antworten
   
HaBOT
 
- Anzeige -

Werbung ist gerade online    
Alt 16.12.11, 14:21   #3 (permalink)
Themenstarter
 
Registriert seit: 06.06.09
Thunderb0lt Leistung: 8086
Likes: 6
Standard

Ich initialisiere den Mutex im Konstruktor, wie im Code oben geschrieben.

Code:
pthread_mutexattr_t attr;
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);

int err = pthread_mutex_init( &mutex, &attr );
if( err )
{
          logger << "Failed to init mutex: "
                 << strerror(err);
}
Ich habe es auch mit PTHREAD_MUTEX_ERRORCHECK (brachte keine weiteren Erkenntnisse) oder einfach mit
Code:
pthread_mutex_init( &mutex, NULL );
versucht. Immer das selbe Problem.

Übrigens habe ich mich evtl. etwas missverständlich ausgedrückt. Direkt nach der Initialisierung ist der Mutex nicht gesperrt. Ein Entsperren wirft einen entsprechenden Fehler.

Außerdem scheint der Mainthread, der nur lesend auf die Daten zugreift (also nur die Getter aufruft) das Problem nicht zu haben. Scheinbar kann dieser problemlos den Mutex sperren und entsperren.


~~EDIT~~

Je dummer der Fehler, desto länger sucht man ihn
Beim erzeugen des Threads wende ich den Adressoperator auf das Argument an, obwohl es ja bereits ein Zeiger ist. Wenn ich das & entferne funktioniert alles, wie es soll:

Code:
int err = pthread_create( gpsReceiverThread, NULL, Executor::gpsReceivingFunc, gpsInfos);
__________________
A good programmer looks both ways before crossing a one-way street.

Die Politik kann uns nur für so dumm verkaufen, wie wir sind.

Geändert von Thunderb0lt (21.12.11 um 18:38 Uhr)
Thunderb0lt ist offline   Mit Zitat antworten
Antwort
   
- Anzeige -

Werbung ist gerade online    

[HaBo] » Software Home » Code Kitchen » [gelöst] Mutex nach Initialisierung gelockt!?
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind aus
Pingbacks sind aus
Refbacks sind aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Initialisierung von Hardware Mani Hardware Probleme 4 26.11.08 21:25
Thread und Mutex Dawen Code Kitchen 0 09.03.07 16:44
suche Mutex (locking) soox (Web-) Design und webbasierte Sprachen 4 26.02.07 12:29
Virtual Pc - Netzwerkadatper Initialisierung phonix28888 Applikationen 0 13.10.06 01:19
uhr wird als werbung erkannt und gelockt :( pacman (Web-) Design und webbasierte Sprachen 4 11.07.04 17:32


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61