ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Just started with threads. And are now having a pretty strange problem/error. I's probably not strange at all, just me not understanding
Anyway, I would really appreciate if someone could help me with this.
Attached some code in wich the error occur.
First, there's a Thread class. It's not very big, just some basics. And then a Mutex class, pretty straight forward. I have then done a class (MutexTest) for testing the Mutex class. It has a getPtr() method that returns a pointer to an int. In the getPtr() method I have a little loop that sets the pointer to zero a few times, so if another thread wants to write to the pointer, the app segfaults. It works as I planned as long as I dont lock/unlock the mutex Last I have a class (ThreadTest) for testing the Tread class, that retrieves the pointer from a MutexTest class to write to - segfaulting the app (if no mutex is used). Now, the problem is that when i use a mutex, it still segfaults (the getPtr() returns zero). But just sometimes. And I have no idea why. If someone could help me pointing out what's wrong with my code I'd be very thankful.
Code:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
class Thread {
public:
Thread(void) { }
virtual ~Thread(void) { }
public:
virtual void run(void) { // Create and run thread
int ret;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
ret = pthread_create(&_thread, &attr, Thread::entryPoint, static_cast<void*>(this));
pthread_attr_destroy(&attr);
//if(ret) throw Error("Could not create thread");
}
void wait(void) const { pthread_join(_thread, 0); } // Join thread
protected:
virtual void exec(void) = 0; // Virtual method to override
private:
static void* entryPoint(void* pthis) { // Static entry for thread
Thread* pt = static_cast<Thread*>(pthis);
pt->exec();
return 0;
}
private:
pthread_t _thread;
};
class Mutex {
public:
Mutex(void) {
pthread_mutex_init(&_mutex, 0);
}
virtual ~Mutex(void) {
pthread_mutex_destroy(&_mutex);
}
public:
void lock(void) {
//printf("locking mutex..\n");
pthread_mutex_lock(&_mutex);
//printf("mutex locked\n");
}
void unlock(void) {
//printf("unlocking mutex..\n");
pthread_mutex_unlock(&_mutex);
//printf("mutex unlocked\n");
}
private:
pthread_mutex_t _mutex;
};
class MutexTest {
public:
MutexTest() { _ptr = new int; }
virtual ~MutexTest() { delete _ptr; }
public:
int* getPtr(void) {
_mutex.lock();
int* temp;
temp = _ptr; // backup pointer
for(int i = 0; i < 10; i++) {
_ptr = 0; usleep(2); // set pointer to 0 a few times to generate segfault when set in ThreadTest class
}
_ptr = temp; // restore pointer
_mutex.unlock();
return _ptr;
}
private:
Mutex _mutex;
int* _ptr;
};
class ThreadTest : public Thread {
public:
ThreadTest() { }
virtual ~ThreadTest() { }
private:
void exec(void) { // override exec from Thread class
printf("entering thread: %u\n", (int)pthread_self());
int* x;
for(int i = 0; i < 10; i++) {
//printf("i = %d\n", i);
x = _mtest->getPtr(); // get pointer from MutexTest class
//printf("x = %d\n", (int)x);
*x = 1; // set pointer to generate segfault
usleep(10); // sleep to let other ThreadTest object call getPtr() in MutexTest
}
}
public:
void setMutexTest(MutexTest* mtest) { // set MutexTest object to call getPtr() from
_mtest = mtest;
}
private:
MutexTest* _mtest;
};
int main(int argc, char** argv)
{
MutexTest mutex_test;
ThreadTest thread_test[2];
for(int i = 0; i < 2; i++) {
thread_test[i].setMutexTest(&mutex_test);
thread_test[i].run();
}
thread_test[0].wait();
thread_test[1].wait();
return 0;
}
Your problem is that you unlock, THEN return _ptr. The problem w/ this is that _ptr's value can change to 0 after "_mutex.unlock()", but before "return _ptr." What you have to do is assign _ptr to a local temporary variable, then return that, like this:
Code:
_ptr = temp; // restore pointer
temp = _ptr; // looks redundant doesn't it, but it gets the point across ;)
_mutex.unlock();
return temp;
Of course, why didn't I see that Just not used to that kind of thinking yet. Now it works perfectly. Thank you very much for your help, and fast too. You just made my day, and LQ my new favorite forum
Thats an interesting way of starting a thread but I would have to say I don't like it
I suppose you are going to inherit anytype of threading job from thread and run it using the virtual func. correct?
I would see a job as "has a" thread not "is a" thread and this would just mess up your thread starter.
I had the same sort of concerns awhile back and posted the answer I came up with on LQ which you may want to use or just look at it, the link to the source is broken due to fly by night free hosts but if you would like the source just email me using the LQ message feature and I'll bounce it over. http://www.linuxquestions.org/questi...d.php?t=466807
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.