Issue with the thread
-
@jsulm : Actually the camera class has following line
camera->GrabOne(100,ptrGrabResult,TimeoutHandling_ThrowException);
where my program terminates.
Actually my one lib file is compiled in release mode so when i try to run the program in debug mode i get error message as unable to initialize the gdb. -
@jsulm said in Issue with the thread:
Did you check that camera is a valid pointer at that time?
-> How to check it?And what type of crash is it? SIGSEGV or something else?
-> Have no idea. I try using the try catch but did not get any exception. -
-
@jsulm : Yes camera is a valid pointer.
Also what i have observed that when i run the frame processing thread continuously it is creating the issue.
When i only run the frame capture thread everything is fine.
Once again would like to highlight this:connect(threadProcessFrame, SIGNAL(started()), processFrame, SLOT(doWork()));
connect(processFrame, SIGNAL(finished()), processFrame, SLOT(requestReWork()));
connect(processFrame, SIGNAL(resumeWork()), processFrame, SLOT(doReWork()));
connect(processFrame, SIGNAL(retrying()),processFrame,SLOT(requestReWork()));Do you thing running the thread indefinately using the requestReWork slot is causing the issue?
connect(processFrame, SIGNAL(finished()), processFrame, SLOT(requestReWork())); -
@Kira said in Issue with the thread:
connect(processFrame, SIGNAL(finished()), processFrame, SLOT(requestReWork()));
Actually this thread should not finish until you terminate it. Instead it should wait for new work package coming in via signal/slot.
-
@jsulm : Hi i was just analysing the code and found out that may be process frame thread is still executing when the capture frame is invoked.
Work around: I replaced the camera function with reading a image from the disk but still the issue occured. So i concluded that it cannot be issue of camera.
I also observed that frame processing thread was still executing when camera Thread is called program terminated with log that thread was invoke.
Though the two threads are independent may be something is conflicting.
How can i make them independent ?? -
@jsulm : I think i have figured where exactly the issue is:
If suppose the processFrame thread is working camera request a frame and processframe haven't finished working. Below signal will will be generated:
connect(workerPrimaryCamera,SIGNAL(workRequested()), threadPrimaryCamera, SLOT(start()),Qt::DirectConnection);
And since it is Qt::DirectConnection it will immediately try to invoke slot causing a conflict and somehow cause a crash.
What do you think ?
Actually as per my program requirements i have to get the frame from the camera when demanded.
I can continuously fetch the frame in a thread but it is not acceptable as there are chances of getting older frame.
Can you please suggest any sophisticated way to implement the same.
Thanks -
@Kira said in Issue with the thread:
Qt::DirectConnection
I don't think this is a good idea when connecting signals/slots between different threads, should be queued connection.
-
@Kira said in Issue with the thread:
And since it is Qt::DirectConnection it will immediately try to invoke slot causing a conflict and somehow cause a crash.
What do you think ?it's worse than that, with a forced DirectConnection, the SLOT is executed in the calling thread.
Without any QMutex or similar, this is highly likely the cause of your problems.
-
Hi @Kira !
Yes, the Qt::DirectConnection is a problem with threads. You should make sure you are using the Qt::QueuedConnection and that you are passing a buffer of data that the processing thread can take ownership of and destroy when finished. I like to use QSharedData/QSharedDataPointer so the cleanup is scoped and easy.
The nice thing about queued connections is that mutexing can be minimal when using the QSharedData/QSharedDataPointer (if at all) and the data will "queue" up so you can access it as fast as you need to.
I process hundreds of GNSS and CAN messages per second so you should be OK.
-
@Buckwheat said in Issue with the thread:
Yes, the Qt::DirectConnection is a problem with threads.
I object to that statement! I have a 5 years old or so C++ syntax parser that is threaded and uses direct connections exclusively. I would argue that one should know what
Qt::DirectConnection
implies, however. Same goes forQt::QueuedConnection
- just mindlessly using queued calls over whatever thread the objects happen to be in means you're just as mindlessly copying data around without a reason. What one should default to is the default -Qt::AutoConnection
, and use a direct or a queued connection when and only when that's what is exactly, explicitly, supposed to happen. -
@jsulm @J-Hilk @Buckwheat @kshegunov :
Guys thanks for response. I problem seems to be with camera thread. Please have a look over the connections:
connect(camera,SIGNAL(workRequested()), threadCamera, SLOT(start()),Qt::DirectConnection);
connect(threadCamera, SIGNAL(started()), camera, SLOT(doWork()),Qt::DirectConnection);
connect(camera,SIGNAL(frame(cv::Mat)),this,SLOT(updateFrame(cv::Mat)),Qt::DirectConnection);
connect(camera, SIGNAL(finished()),threadCamera,SLOT(quit()),Qt::DirectConnection);I am following the following approch:
Constructor:
camera->moveToThread(threadCamera);
Main Program:
camera->requestWork() // At this point i initialite the thread to fetch frame
what is did after few miiliseconds i again called camera->requestWork() without checking whether
previous thread have been stopped.
As i have used Qt::DirectConnection in all my slots other the first thread used to work forcing other thread to wait but this logic seems to fail at certain instance of time and the program would crash.
If i remove Qt::DirectConnection the slots don't respond.- Please let me know correct way in which i can call the thread ?
- Is not correct to call camera->workRequest multiple time ?
- Does calling camera->workRequest multiple time creates multiple instance or same thread instance is called everytime?
-
@Kira said in Issue with the thread:
If i remove Qt::DirectConnection the slots don't respond.
You're blocking the event loop for that to occur. Don't block the event loop and you're going to be fine. Search the forums, I, personally, have written many posts on that particular topic, so the information is in there.
-
@kshegunov : I have diabled my tensorflow library for my debugger to work.
I am getting the following exception from the thread.Add debugger shows error at following line of alloc.h:
uchar* udata = (uchar*)malloc(size + sizeof(void*) + CV_MALLOC_ALIGN); -
@kshegunov : Finally resolved and learnt the importance of debugger in life.
I just commented the tensorflow lib which was a release mode lib and was causing the gdb error.Exact Issue:
I have created a QPair which in which i inserted a image with a processed flag set to false.
My tread whereas in background would run independently and try to process the image and set the processed flag to true.
There was a condition in my loop where led the thread to access a certain location which was not present in the QPair list and caused the trigger to terminate abnormally.
Thanks to the debugger the issue was clear. -
@kshegunov said in Issue with the thread:
@kshegunov I am glad you take offense. But, the default behavior for connection seems to be queued connection when crossing thread boundaries. I have found NO exception to this in the last 7 years so obviously the Qt designers thought there might be a problem. This queuing is why you can Q_EMIT data from a thread and put it into a GUI control which can only be done from the main thread. Also, I just said "Qt::QueuedConnection is no problems with threads". I would assume he is using the defaults in his thread.
As for copying, Sending a QSharedDataPointer is 4 bytes and is reference counted. NO COPYING except a pointer. Please read carefully before making "mindlessly" making judgements.
As 99% of my posts say, it is all in your design. Know what you are doing and what protections are offered. If you need to queue packets, QSharedDataPointer is great and it manages the pointers properly.
So, in summary, feel as offended as you like. It is a free forum and we can react how we like!