1

I'm having trouble using std::mutex ( cpp ) to serialize access to a shared resource (I need to use libmodbus which is not thread-safe. I'm currently trying to serialize access to the modbus_write_registers function by placing a mutex.lock() statement before it. I release the mutex near the end of my function.)

the essence of my problem is that it looks like several threads are able to acquire a lock on a mutex simultaneously.

I've tried several different compiler versions, I've tried using std::lock_guard the results are the same.

here are some technicals :

gcc 7.4.0   ( 6.3.0 , 5.4.0)
libstdc++.so.6.0.26
building with cmake , 
c++ version 14 (set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14"))

some code :

my write function

std::thread::id this_id = std::this_thread::get_id();

m.lock()

std::cout << "@@@@@@@@@@ FfrModBusClient::setRegistersOnePacket after lock tid " << this_id << std::endl;

ModbusRetCode = modbus_write_registers(pToModbusServer, AddressToWrite, RegsToWrite, RegsValues);

std::cout << "FfrModBusClient::setRegistersOnePacket after modbus_write & before sleep,  id " <<  this_id << std::endl;

my main :

struct TestThreadParameters
{
    int               Id;
    FfrModBusClient * pSharedModbusClient;
    int               Port;
    std::string       Ip;

};

void TestInThread(const TestThreadParameters Parameters)
.
.
.

void main :
TestThreadParameters    TTP;
TTP.Ip = IPAddress;
TTP.Port = Port;
TTP.pSharedModbusClient = &ModbusClientObject;
std::thread a1(TestInThread,TTP);
.
.
std::thread a9(TestInThread,TTP);
a1.join()....
  • ModbusClientObject is an object of a class that has a std::mutex ComLock as a private member, and a "libmodbus" context data member pToModbusServer...

  • to the best of my knowledge I'm passing the address of 1 object to all threads, I've made sure all threads show the same value for its address at runtime. and I don't explicitly create another instance of the Modbus wrapper class anywhere.

my terminal shows successive "after lock" messages with no "after modbus_write & before sleep" messages between them and the matching modbus_write_registers call fail with various memory corruption errors (as expected from a lib that is not thread-safe).

Any help would be appreciated.
:-) omer

Amol Gangadhare
  • 1,059
  • 2
  • 11
  • 24
  • i'm using pthread libpthread-stubs0-dev 0.3-4 as far as i can tell its the currently supported/official version – omer brandis Aug 05 '20 at 08:47
  • 2
    Add code to show how `m` is related to your ModbusClientObject object. – Botje Aug 05 '20 at 08:50
  • 2
    My psychic powers say that `m` is a different object in each thread. – TainToTain Aug 05 '20 at 09:17
  • If you think its your system, make a small example program to simulate the issue. As others have said though, Chances are high its your code, not C++ or the STL. – g-radam Aug 05 '20 at 09:25
  • m is defined as a private member of the class. i can show the code , but theres not much to see. moreover, i've also tried moving its definition to the cpp file , same results :-( – omer brandis Aug 05 '20 at 09:55
  • now tried declaring m as static (and placing definition in .cpp file ) - same results – omer brandis Aug 05 '20 at 10:10
  • With concurrency/multi-threading the devil is in the detail. You really need to show more code -- preferably a [mcve]. – G.M. Aug 05 '20 at 10:13
  • wrote a minimal example - IT DID NOT REPRODUCE. any ideas about how to debug the original ? is there a way to Id the mutex used ? – omer brandis Aug 05 '20 at 10:45
  • Just log the address – Useless Aug 05 '20 at 10:46
  • converted all methods in class to use lock_guard, seems look significantly better now. could mean that i unlocked somewhere ... – omer brandis Aug 05 '20 at 11:11

1 Answers1

0

after confirming that std::mutex works as expected on my pc, the only thing that is left is some sort of logical bug where i perform an unlock by mistake.