pthread anfänger



  • Hallo zusammen,

    bin grade dabei Multithreading zu lernen (mit pthreads) und wollte mal jemand Fortgeschrittenen über meinen Ansatz urteilen lassen.

    Hab eine Timer Klasse geschrieben, deren timing-funktion in einem eigenen Thread läuft.

    Hier der Code:

    Header:

    typedef int MyCallback(int time, void* ptr);
    
    class ThreadedTimer
    {
    public:
    	ThreadedTimer();
    	virtual ~ThreadedTimer();
    	void SetCallback(MyCallback* cb);
    	void start(int interval);
    	void stop();
    	static void* run(void* ptr);
    	int counter;
    	int rc;
    
    private:
    
    	int (*p)(int time, void* ptr);
    	bool running;
    	int _time;
    	pthread_t thread;
    	pthread_attr_t attr;
    
    };
    

    ThreadedTimer.cpp

    #include "ThreadedTimer.h"
    
    ThreadedTimer::ThreadedTimer()
    {
    	running = false;
    	counter = 0;
    }
    
    ThreadedTimer::~ThreadedTimer()
    {
    }
    
    // Thread start function
    void* ThreadedTimer::run(void* ptr) {
    
    	ThreadedTimer* data = (ThreadedTimer*) ptr;
    
    	while (data->running) {
    
    		usleep(data->_time*1000);
    		data->counter++;
    		std::cout << "thread running for ";
    		data->p(data->counter *data->_time, data);
    
    	}
    
    	std::cout << "thread stopping" << std::endl;
    	pthread_exit((void*)0);
    }
    
    void ThreadedTimer::stop() {
    
    	running = false;
    	_time = 0;
    
    }
    
    void ThreadedTimer::start(int interval) {
    
    	running = true;
    	this->_time = interval;
    
    	// Create detached thread
    	pthread_attr_init(&attr);
    	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    	std::cout << "thread creation" << std::endl;
    	rc = pthread_create(&thread, &attr, run, (void*)this);
    
    }
    
    void ThreadedTimer::SetCallback(MyCallback* cb) {
    
    	p = cb;
    
    }
    

    Und die Testklasse:

    #include "ThreadedTimer.h"
    
    class TestClass {
    
    public:
    
    	TestClass();
    	void stop();
    
    private:
    
    	static int TheCallback(int time, void* ptr);
    	ThreadedTimer* timer;
    };
    
    int TestClass::TheCallback(int a, void *ptr) {
    
    	std::cout << (float)a/1000 << " seconds" << std::endl;
    	return 0;
    
    }
    
    TestClass::TestClass() {
    
    	timer = new ThreadedTimer();
    	timer->SetCallback(TheCallback);
    	timer->start(500);
    
    }
    
    void TestClass::stop() {
    
    	timer->stop();
    }
    
    int main()
    {
    
    	std::cout << "before thread creation" << std::endl;
    	TestClass* A = new TestClass();
    	std::cout << "after thread creation" << std::endl;
    
    	usleep(5000000);
    
    	A->stop();
    	std::cout << "main thread terminating" << std::endl;
    
    	return 0;
    
    }
    

    Funktioniert eigentlich soweit ich das beurteilen kann ganz gut, ich wollte mich jedoch mal versichern ob das ein vernünftiger Weg wie man sowas mit Threads implementiert.

    Vielen Dank !



  • Es ist nicht vernünfig:

    1. Die Funktion, die an pthread_create übergeben wird, darf nicht statische Funktion einer Klasse sein. Sie muss eine freistehende extern "C" Funktion sein.

    2. Der Zugriff auf running ist nicht synchronisiert. Keiner garantiert, dass der Thread jemals die Veränderung mitkriegt.


Anmelden zum Antworten