boost::thread kopiert Objekt/löscht Objekt automatisch?



  • Hallo,
    ich habe mal wieder ein Problem:

    boost::ptr_vector<ReadData> readData(this->mipMaps().size());
    
    for (std::size_t i = 0; i < this->mipMaps().size(); ++i)
    {
    	...
    	readData.push_back(new ReadData(*this->mipMaps()[i], buffer, bufferSize, loader));
    }
    
    boost::thread_group threadGroup; // added threads are being destroyed automatically when group is being destroyed
    
    for (std::size_t i = 0; i < readData.size(); ++i)
    	threadGroup.create_thread(boost::bind(&readMipMapJpeg, &readData[i]));
    
    threadGroup.join_all(); // wait for all threads have finished
    

    Ich erzeuge einen pointer container, damit das Zeug am Ende automatisch wieder gelöscht wird. Ein Pointer auf ReadData wird bei der Thread-Erzeugung übergeben.

    void readMipMapJpeg(ReadData *readData)
    {
    readData->lock();
    ...
    readData->unlock();
    }
    

    ReadData erbt von boost::mutex und kann deshalb gelockt werden. Das Problem ist nun, wenn die obere scope nach "join_all()" verlassen wird, müssten eigentlich die Threads und die ReadData-Objekte gelöscht werden, stattdessen kommt aber:

    /usr/include/boost-1_46/boost/thread/pthread/mutex.hpp:47: boost::mutex::~mutex(): Assertion `!pthread_mutex_destroy(&m)' failed.

    Zuvor hatte ich eine alte Version getestet, in der ReadData nicht von boost::mutex erbt und ich das lock-Zeug nicht drinnen hatte (der Rest war gleich). Lustigerweise wurde dann aber bei der Schreibfunktion (die im Grunde gleich aussieht) ein scoped-Pointer, der ein Member eines WriteData-Objekts war zweimal freigegeben, was auch zum Absturz führte. Deshalb sieht es für mich irgendwie danach aus als würden die ReadData-Objekte immer zweimal gelöscht werden.
    Hier noch die Deklaration von ReadData:

    struct ReadData : public boost::mutex
    {
    	ReadData(Blp::MipMap &mipMap, unsigned char * const data, const std::size_t dataSize, const JpegLoader &loader) : mipMap(mipMap), data(data), dataSize(dataSize), loader(loader)
    	{
    	}
    
    	Blp::MipMap &mipMap;
    	unsigned char * const data;
    	const std::size_t dataSize;
    	const JpegLoader &loader;
    	std::string stateMessage;
    };
    


  • 1. Leite nicht von boost::mutex ab. Die Klasse ist nicht dafür designed eine Basisklasse zu sein.
    2. Benutze scoped_lock, um das Freigeben des mutex zu automatisiseren. Der Fehler sieht so aus, als würde etwas doppelt freigeben oder freigegebn was nie gelockt war oder etwas in der Richtung.


Anmelden zum Antworten