2013-09-27 01:48, Gavin Lambert skrev:
On 9/27/2013 11:16 AM, Quoth Davies, John:
I have the following code and it terminates as expected. When I call the destructor it interrupts the thread.
But if I change the this_thread::sleep to this_thread::yield the join() never happens and the program hangs.
I must be misunderstanding yield. But I really don’t want a sleep if possible.
The main thing to remember about yield() is that it's permitted to be a no-op if the OS feels like it, and in particular on single-core systems it will completely block lower priority threads from running.
Also note that unlike sleep, yield is not listed as an interruption point. So when you're using yield you're basically setting up a 100% CPU loop that can't be interrupted, which is why it's hanging. You *could* fix part of that by adding an explicit interruption point, but that's not the ideal solution.
Given that it looks like you basically want to block until there's work to do in the queue, you might want to consider using a mutex and condition_variable (notifying the condition variable when you push something into the queue, and waiting on it when the queue is empty). You're going to need a mutex on the queue operations anyway unless you're using something that's internally thread-safe.
You also might want to consider using something like Boost.Asio instead. Its io_service allows you to queue arbitrary function objects to a specific thread (or threadpool) in a thread-safe manner, even if you don't want to use the actual I/O parts.
Having problems with a three thread program. The application is using Boost 1.54 on a Beaglebone Black ARM target. using a single core Cortex-A8. The first thread reads data from a serial port, and store a record with the info in a list, The second thread reads from the list, and upioads data from the list to a webserver. The list is protected by a boost::mutex Queue_Lock; The third thread initializes the two first two threads and the ends up executing io_service.run(); io_service is related to an UDP based debug channel using boost::asio. By calling DebugPort.WriteLine you send a string to the UDP debug channel. The UDP debug channel, is protected by another mutex, since both main threads will use it. THREAD_WRITE is a conditional DebugPort.WriteLine, and normally this is a NOP. The second thread calls a number of routines which tries to allocate a mutex, and if not, it will yield. It looks like the second thread hangs in one of these routines. This does not occur frequently. The program was running for a week before it happened the last time. There is not enough debug prints right now to determine why, and since the application was built using a cross compiler, there is not a lot of symbols available. When attaching using gdb, we saw that it was in a mutex wait in the libpthread library Typical code. bool Server::QueueEmpty(void) { bool empty; try { THREAD_WRITE("Checking SendQueue", YELLOW); empty = true; while (1) { boost::mutex::scoped_lock lock(Queue_Lock, boost::try_to_lock); if (lock) { empty = SendQueue.empty(); break; } else { // Didn't get lock, retry after yield THREAD_WRITE("Sendstart Yielding QueueEmpty", RED); this_thread::yield(); THREAD_WRITE("Sendstart Returning QueueEmpty", RED); } } } catch (std::exception &e) { DebugPort.WriteLine(e.what(), RED); empty = true; } return empty; } Is there an obvious problem with this code? It is using Yield, which I assumed was the right way to release the CPU. Using sleep feels wrong, since I do not want to sleep, I want to wait for the mutex. The first thread implements the mutex in the same way, although not in a subroutine. Am I correct in assuming, that since I use scoped_lock, the mutex will always be released when I exit the while loop with "break;"? Best Regars Ulf Samuelsson
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users