Crash creating QMutexLocker from child QThread - multithreading

I have QMutex and QQueue as member in QThread based class. I'm locking QMutex (by QMutexLocker) in popEvent and pushEvent metods. When I lock it in push method called from main thread it works. When I call pop function from child thread loop it crashes on creating QMutexLock. Whats wrong? Should QMutex and QQueue be global or static? QThread based class is created on main thread heap (heap not stack).

A mutex is "owned" by the thread that holds it. It cannot be released by another thread. You probably want a semaphore, not a mutex.

Related

Condvar behaviour after signal, but before mutex release

I am trying to understand what guarantees I have just after I signalled a condvar.
The basic pattern of usage is, I believe, this (pseudocode):
Consumer Thread:
Mutex.Enter()
while(variable != ready)
Condvar.Wait()
Mutex.Exit()
Producer Thread:
Mutex.Enter()
variable = ready
Condvar.Broadcast()
[Unknown?]
Mutext.Exit()
My question is. What am I guaranteed about the [Unknown] point in the code above? I am still holding the mutex, but what can I know about the state of the consumer?
From the Man page, it is unclear to me what state the producer is in after it broadcasts/signals and before it releases the mutex.
From condition vars:
pthread_cond_wait() blocks the calling thread until the specified condition is signalled. This routine should be called while mutex is locked, and it will automatically release the mutex while it waits. After signal is received and thread is awakened, mutex will be automatically locked for use by the thread. The programmer is then responsible for unlocking mutex when the thread is finished with it.
So, when producer is executing the Unknown section of code, producer is holding the mutex, and the consumer is locked on the mutex until producer releases it.

Why are slots being called from the main thread?

I have a Qt application that has two threads: the main thread that handles the GUI and a second thread that manages network connections. Here is the thread code:
void thread::run()
{
QTcpServer server;
server.connect(&server,SIGNAL(newConnection()),this,SLOT(OnConnect()));
//...
}
When I put a breakpoint at the start of OnConnect() and debug the application, it announces that OnConnect() is being called from the main thread!
How can I have OnConnect() run in the same thread as the QTcpServer?
To give a more thorough answer, look a little deeper into how signal-slot connections and thread contexts interact. Basically, for more connections (auto-connect), the slot will be directly called if both the emitter and the receiver are in the same thread context, otherwise it will be a queued connection, and the slot will be run in the thread context of the object that contains the slot. In this case, it must be queued, which implies that your thread is part of the main application's thread context, not its own. This is reinforced by the documentation Qt provides for an overview of its threading, where it states that the QThread instance is "owned" by the thread context that created it, not the thread context that it represents. This means you have three main choices:
You can use moveToThread() to move the thread into its own context. Note that this may cause problems when deleting the thread unless you move it back to the context where it will be destroyed, and this can only be done in the source-thread context, so it would have to be done before the run function exited.
You can treat the QThread instance as a handle to the thread, not as being part of the thread itself. If you need things done in the context of the new thread, create a different object to handle those, and instantiate them in the context of the new thread (inside the run function). This is what I would recommend.
Force a direct connection. This means you would need to ensure the code running in the slot is thread-safe, ignoring Qt's built-in methods of making those functions thread-safe. This is what you have done.
It seems like the problem was that I wasn't passing Qt::DirectConnection as the last parameter of connect().
After adding that, it worked.

some questions regarding pthread_mutex_lock

when a thread1 already acquired a lock on mutex object, if thread2 tries to acquire a lock on the same mutex object, thread2 will be blocked.
here are my questions:
1. how will thread2 come to know that mutex object is unlocked?
2. will thread2 try to acquire lock at predifined intervals of time?
I sense a misunderstanding of how a mutex works. When thread 2 tries to acquire a mutex that is already owned by thread 1, the call that tries to take the mutex will not return until the mutex becomes available (unless you have a timeout with trylock() variant).
So thread 2 does not need to loop there and keep trying to take the mutex (unless you're using a timeout so you can abort trying to take the mutex based on some other condition like a cancel condition).
This is really OS dependant, but what usually happens is that thread2 gets suspended and put on a wait list maintained by the mutex. When the mutex becomes available, a thread on the mutex's waitlist gets removed from the list and put back on the list of active threads. The OS can then schedule it like it usually would. thread2 is totally quiescent until it can acquire the mutex.

Question about QThread implementation

A QThread object represents a single thread of execution. But is the OS thread created when the QThread object is created, or when the start() method is called?
I'm interested in whether I can have several QThread objects lying around, and the OS will create threads on start() and kill them after run() returns, and then I can reuse the QThread objects again. But I don't want to hold OS resources while the QThread objects are not doing anything.
(for the record, I'm aware of QtConcurrent and the QThreadPool, and no, they don't satisfy my needs in this situation)
In Linux the thread object is created (via pthread_create) during the QThread::start method. It looks about the same with Windows.
You can see the source here:
Unix: http://qt.gitorious.org/qt/qt/blobs/master/src/corelib/thread/qthread_unix.cpp (line 542).
Windows: http://qt.gitorious.org/qt/qt/blobs/master/src/corelib/thread/qthread_win.cpp (line 419).

QMutex stuck in locked state

I have a function which is part of a class and in this function there is a mutex.lock at the beginning of the function and a mutex.unlock just before its return. Now I have encountered a situation where the mutex is stuck in the locked state. What could be doing this if this function is the only place where I use that mutex to lock and unlock. The function is called from the main thread and from 1 or 2 other QThreads.
UPDATE: the problem was due to the thread not sleeping in between function calls. Maybe the lack of a sleep relocked the mutex really fast? You could also call yieldCurrentThread();
If an exception is thrown in the function the unlock() at the end might not get executed. To make sure the QMutex gets unlocked in such cases you can do the locking with a QMutexLocker object. This object will automatically unlock the mutex when it get's destroyed, even if that happens during stack unwinding after an exception.
On Mac OS X I had QMutex hangs even in a 100% correct logic. I made a wrapper call around QMutex, which increased/decreased an atomic reference count, and QMutex was hanging at a place, where the reference count was signifying no held mutex.
This has happened to me once in Qt3, and once more in the recent Qt (4.6.2 or 4.7.0, I don't remember). Replacing QMutex with a custom class, that goes directly to OS primitives - solved the problem.
Note however, this problem only occurred on OS X in my case. On Windows the same code was working perfectly.
The mutex was relocking right after unlocking from the same QThread so fast that the main thread didn't have time to lock it back. Adding a sleep or yieldCurrentThread() fixed the problem
My guess is that one of the other threads that calls this function is still holding the lock, and has not released it, so the next thread that tries to enter that section of code, has to wait until the lock is releasd.
Are there any blocking calls inside the lock/unlock code?
From the Qt QMutex Documentation:
When you call lock() in a thread,
other threads that try to call lock()
in the same place will block until the
thread that got the lock calls
unlock()

Resources