Opened 7 years ago

Last modified 6 years ago

#11499 assigned Bugs

windows - exception lock_error while intensive locking/unlocking of shared_mutex on many threads

Reported by: andrew maclean <agm@…> Owned by: viboes
Milestone: To Be Determined Component: thread
Version: Boost 1.59.0 Severity: Problem
Keywords: Cc:

Description

#include "stdafx.h"
#include <boost/thread/shared_mutex.hpp>
#include <thread>
#include <mutex>
#include <shared_mutex>
#include <atomic>
#include <vector>

using MutexT = boost::shared_mutex;
using ReaderLockT = std::lock_guard<MutexT>;
using WriterLockT = std::shared_lock<MutexT>;

MutexT gMutex;
std::atomic<bool> running = true;

long reads = 0;

void read()
{
   while (running)
   {
      ReaderLockT lock(gMutex);
      std::this_thread::yield();
      ++reads;
   }
}

int main()
{
   using namespace std;

   vector<thread> threads;
   for (int i = 0; i < 256; ++i)
   {
      threads.emplace_back(thread(read));
   }

   string str;

   getline(std::cin, str);
   running = false;

   for (auto& thread : threads)
   {
      thread.join();
   }

   return 0;
}


Attachments (1)

shared_mutex_exception.png (52.3 KB ) - added by agm@… 7 years ago.

Download all attachments as: .zip

Change History (14)

comment:1 by andrew maclean <agm@…>, 7 years ago

Version: Boost 1.57.0Boost 1.58.0

comment:2 by andrew maclean <agm@…>, 7 years ago

Version: Boost 1.58.0Boost 1.59.0

comment:3 by andrew maclean <agm@…>, 7 years ago

Component: Nonethread
Owner: set to Anthony Williams

in reply to:  description comment:4 by andrew maclean <agm@…>, 7 years ago

Replying to andrew maclean <agm@…>:

#include "stdafx.h"
#include <boost/thread/shared_mutex.hpp>
#include <thread>
#include <mutex>
#include <shared_mutex>
#include <atomic>
#include <vector>

using MutexT = boost::shared_mutex;
using ReaderLockT = std::lock_guard<MutexT>;
using WriterLockT = std::shared_lock<MutexT>;

MutexT gMutex;
std::atomic<bool> running = true;


void threadfunc()
{
   while (running)
   {
      ReaderLockT lock(gMutex);  // exception - eventually... (ymmv)
      std::this_thread::yield();
   }
}

int main()
{
   using namespace std;

   vector<thread> threads;
   for (int i = 0; i < 256; ++i)
   {
      threads.emplace_back(thread(threadfunc));
   }

   string str;

   getline(std::cin, str);
   running = false;

   for (auto& thread : threads)
   {
      thread.join();
   }

   return 0;
}


comment:5 by viboes, 7 years ago

Owner: changed from Anthony Williams to viboes
Status: newassigned

comment:6 by viboes, 7 years ago

I'm unable to reproduce it on a MAC (I don't have a Windows machine available). Please, could you give more information?

by agm@…, 7 years ago

Attachment: shared_mutex_exception.png added

comment:7 by viboes, 7 years ago

Where your example is using timed_lock?

comment:8 by andrew maclean <agm@…>, 7 years ago

In shared_mutex.hpp @393 lock() member function

void lock() {

#if defined BOOST_THREAD_USES_DATETIME

BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));

#else

BOOST_VERIFY(try_lock_until(chrono::steady_clock::now()));

#endif

}

comment:9 by viboes, 7 years ago

Please, could you try using a version >= 0

#define BOOST_THREAD_VERSION 4
#include <boost/thread/shared_mutex.hpp>
....

If you can not, could you try replacing

 #if defined BOOST_THREAD_USES_DATETIME

    BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));

#else

    BOOST_VERIFY(try_lock_until(chrono::steady_clock::now()));

#endif 

by

    BOOST_VERIFY(try_lock_until(chrono::steady_clock::now()));

The same for lock_shared.

Thanks for your help, Vicente

Last edited 7 years ago by viboes (previous) (diff)

comment:11 by viboes, 7 years ago

It seems this change doesn't works at all. I've rolled back the change.

comment:12 by viboes, 7 years ago

Summary: exception lock_error while intensive locking/unlocking of shared_mutex on many threadswindows - exception lock_error while intensive locking/unlocking of shared_mutex on many threads

comment:13 by viboes, 6 years ago

You can define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN to get the generic implementation. It is slower but IMHO it has less bugs.

See #12386

Note: See TracTickets for help on using tickets.