关于多线程访问同一个对象的问题

时间:2022-05-22 20:39:27
1  多个线程操作同一个对象,并通过该对象成员函数取得该对象成员值,之前用过互锁函数,但是一旦一个线程block在里面出不来了,则后面等待该信号的线程都就堵塞了,程序也重启了,现在想改为去掉互斥锁,因为只是操作该对象成员函数取得值,并没有进行写入修改,大家觉得这样做可行吗?
2  非singleton模式通过静态成员函数GetInstance每次调用都会获得一个实例保存在一个static map中,如果同一个进程中,多个多线程的同一类对象在各自的线程中调用GetInstance,那么获得所有的实例应该是位于同一个map中吧,所以加了互斥锁来同步,如果因为其中一个线程造成堵塞,那么其余的再获取实例操作该map的线程都会堵塞住,哎,有没有好的解决办法啊??

10 个解决方案

#1


// 只读不写应该可以不加锁。

#2


关于windows核心编程里的旋转锁,如何修改能让它在一个线程死掉不会释放mutex的情况下,另一个等待信号量的线程不会死等下去。在下面代码中WaitForSingleObject(m_hEvent, INFINITE);修改为
WaitForSingleObject(m_hEvent, 60);可以吧?那在返回后如何处理m_lLockCount和m_lRecurseCount会使后面的线程都不锁呢?高手给解决的彻底一些吧,怕自己解决出问题

void Enter()
{
   //Spin, trying to get the optimized mutex
   if(TryEnter()) 
  return;  // We got it, return

   //We couldn't get the optimized mutex, wait for it.
   DWORD dwThreadId = GetCurrentThreadId();

   if(InterlockedIncrement(&m_pSharedInfo->m_lLockCount) == 1)
   {
  //optimized mutex is unowned, let this thread own it once
  m_pSharedInfo->m_dwThreadId = dwThreadId;
  m_pSharedInfo->m_lRecurseCount = 1;
   }
   else
   {
  if(m_pSharedInfo->m_dwThreadId == dwThreadId)
  {
 //If optimized mutex is owned by this thread, own it again
 m_pSharedInfo->m_lRecurseCount++;
  }
  else
  {
 //optimized mutex is owned by another thread, wait for it
 WaitForSingleObject(m_hEvent, INFINITE);

 //optimized mutex is unowned, let this thread own it once
 m_pSharedInfo->m_dwThreadId = dwThreadId;
 m_pSharedInfo->m_lRecurseCount = 1;
  }
   }
}

#3


只访问 不修改
不加互斥是没问题的

#4


WaitForSingleObject(m_hEvent, 60);
可以通过返回值处理

#5


可否修改为这样呢?会避免死锁死死等待下去,大家觉得可行吗?可是如果这样的话如果两个线程同时等待在60秒后,相继wait返回就失去了锁的意义了。。。该怎么改呢?
void Enter()
{
//Spin, trying to get the optimized mutex
if(TryEnter())  
return; // We got it, return

//We couldn't get the optimized mutex, wait for it.
DWORD dwThreadId = GetCurrentThreadId();

if(InterlockedIncrement(&m_pSharedInfo->m_lLockCount) == 1)
{
//optimized mutex is unowned, let this thread own it once
m_pSharedInfo->m_dwThreadId = dwThreadId;
m_pSharedInfo->m_lRecurseCount = 1;
}
else
{
if(m_pSharedInfo->m_dwThreadId == dwThreadId)
{
//If optimized mutex is owned by this thread, own it again
m_pSharedInfo->m_lRecurseCount++;
}
else
{
//optimized mutex is owned by another thread, wait for it
DWORD reason=WaitForSingleObject(m_hEvent, INFINITE);
if(reason==WAIT_TIMEOUT)
{
  if(--m_pSharedInfo->m_lRecurseCount > 0)
   {
  //We still own the optimized mutex
  InterlockedDecrement(&m_pSharedInfo->m_lLockCount);
   }
}

//optimized mutex is unowned, let this thread own it once
m_pSharedInfo->m_dwThreadId = dwThreadId;
m_pSharedInfo->m_lRecurseCount = 1;
}
}
}

#6


多线程同步是程序员基本的技能..

#7


没人给修改意见么?

#8


DWORD reason=WaitForSingleObject(m_hEvent, INFINITE);
你这是INFINITE如果死锁
怎么可能有返回值
我觉得你还是好好分析一下线程间关系,避免死锁的出现

#9


引用 8 楼 hezhe1008 的回复:
DWORD reason=WaitForSingleObject(m_hEvent, INFINITE);
你这是INFINITE如果死锁
怎么可能有返回值
我觉得你还是好好分析一下线程间关系,避免死锁的出现

哎呀,写错了,我说了是60s的
DWORD reason=WaitForSingleObject(m_hEvent, 60);

#10


对象中加锁

#1


// 只读不写应该可以不加锁。

#2


关于windows核心编程里的旋转锁,如何修改能让它在一个线程死掉不会释放mutex的情况下,另一个等待信号量的线程不会死等下去。在下面代码中WaitForSingleObject(m_hEvent, INFINITE);修改为
WaitForSingleObject(m_hEvent, 60);可以吧?那在返回后如何处理m_lLockCount和m_lRecurseCount会使后面的线程都不锁呢?高手给解决的彻底一些吧,怕自己解决出问题

void Enter()
{
   //Spin, trying to get the optimized mutex
   if(TryEnter()) 
  return;  // We got it, return

   //We couldn't get the optimized mutex, wait for it.
   DWORD dwThreadId = GetCurrentThreadId();

   if(InterlockedIncrement(&m_pSharedInfo->m_lLockCount) == 1)
   {
  //optimized mutex is unowned, let this thread own it once
  m_pSharedInfo->m_dwThreadId = dwThreadId;
  m_pSharedInfo->m_lRecurseCount = 1;
   }
   else
   {
  if(m_pSharedInfo->m_dwThreadId == dwThreadId)
  {
 //If optimized mutex is owned by this thread, own it again
 m_pSharedInfo->m_lRecurseCount++;
  }
  else
  {
 //optimized mutex is owned by another thread, wait for it
 WaitForSingleObject(m_hEvent, INFINITE);

 //optimized mutex is unowned, let this thread own it once
 m_pSharedInfo->m_dwThreadId = dwThreadId;
 m_pSharedInfo->m_lRecurseCount = 1;
  }
   }
}

#3


只访问 不修改
不加互斥是没问题的

#4


WaitForSingleObject(m_hEvent, 60);
可以通过返回值处理

#5


可否修改为这样呢?会避免死锁死死等待下去,大家觉得可行吗?可是如果这样的话如果两个线程同时等待在60秒后,相继wait返回就失去了锁的意义了。。。该怎么改呢?
void Enter()
{
//Spin, trying to get the optimized mutex
if(TryEnter())  
return; // We got it, return

//We couldn't get the optimized mutex, wait for it.
DWORD dwThreadId = GetCurrentThreadId();

if(InterlockedIncrement(&m_pSharedInfo->m_lLockCount) == 1)
{
//optimized mutex is unowned, let this thread own it once
m_pSharedInfo->m_dwThreadId = dwThreadId;
m_pSharedInfo->m_lRecurseCount = 1;
}
else
{
if(m_pSharedInfo->m_dwThreadId == dwThreadId)
{
//If optimized mutex is owned by this thread, own it again
m_pSharedInfo->m_lRecurseCount++;
}
else
{
//optimized mutex is owned by another thread, wait for it
DWORD reason=WaitForSingleObject(m_hEvent, INFINITE);
if(reason==WAIT_TIMEOUT)
{
  if(--m_pSharedInfo->m_lRecurseCount > 0)
   {
  //We still own the optimized mutex
  InterlockedDecrement(&m_pSharedInfo->m_lLockCount);
   }
}

//optimized mutex is unowned, let this thread own it once
m_pSharedInfo->m_dwThreadId = dwThreadId;
m_pSharedInfo->m_lRecurseCount = 1;
}
}
}

#6


多线程同步是程序员基本的技能..

#7


没人给修改意见么?

#8


DWORD reason=WaitForSingleObject(m_hEvent, INFINITE);
你这是INFINITE如果死锁
怎么可能有返回值
我觉得你还是好好分析一下线程间关系,避免死锁的出现

#9


引用 8 楼 hezhe1008 的回复:
DWORD reason=WaitForSingleObject(m_hEvent, INFINITE);
你这是INFINITE如果死锁
怎么可能有返回值
我觉得你还是好好分析一下线程间关系,避免死锁的出现

哎呀,写错了,我说了是60s的
DWORD reason=WaitForSingleObject(m_hEvent, 60);

#10


对象中加锁