// // Concurrently streaming ptime to a std::ostringstream crashes under MinGW-32. // http://jc-bell.com // #include #include #include #include #include namespace P = boost::posix_time; namespace T = boost::this_thread; typedef P::ptime ptime; typedef boost::mutex::scoped_lock scoped_lock; boost::mutex ioLock; ptime LocalTime() { return P::microsec_clock::local_time(); } void ThisCrashes() { static boost::mutex myLock; ptime nowPT = LocalTime(); // Wrap even the ostringstream in a lock and it works. //scoped_lock lk(myLock); std::ostringstream oss; // local to this function. // Wrap just the ostream insertion in a mutex and it works better, but still crashes. //scoped_lock lk(myLock); // The following line is the culprit. Comment it out and no crash. oss << nowPT << "; " << nowPT; //lk.unlock(); std::string other = oss.str(); } int GetRand(int maxRand) { std::size_t r = std::rand(); return (r * maxRand) / RAND_MAX; } void CrasherThread() { ptime endTime = LocalTime() + P::seconds(300); int iterCount = 0; while (LocalTime() < endTime) // iterCount < 1000) // { T::sleep(P::milliseconds(GetRand(100))); ++iterCount; if ((iterCount % 50) == 0) { scoped_lock lk(ioLock); std::cout << "Thread " << T::get_id() << " " << iterCount << std::endl; } ThisCrashes(); } scoped_lock lk(ioLock); std::cout << "Thread " << T::get_id() << " done: " << iterCount << std::endl; } int main(int argc, char *argv[]) { std::cout << "Starting..." << std::endl; boost::thread_group tg; // Make just one thread and it works. for (int i = 0; i < 10; ++i) tg.create_thread(CrasherThread); tg.join_all(); std::cout << "Exiting normally..." << std::endl; return 0; }