gpt4 book ai didi

c++ - 带有信号量的线程安全单例问题

转载 作者:可可西里 更新时间:2023-11-01 10:42:20 26 4
gpt4 key购买 nike

我写了一个简单的单例应用程序。

下面是我的示例主类

// ThreadsafeSingletonUsingSemaphore.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include "MySingleton.h"
using namespace std;

int i =0;
#define THREADCOUNT 100
DWORD WINAPI ThreadProc(LPVOID lParam);
HANDLE g_semaphore = NULL;

int _tmain(int argc, _TCHAR* argv[])
{
g_semaphore = CreateSemaphore(NULL,1,1,_T("TreadOne"));
HANDLE hThread[THREADCOUNT];
DWORD aThreadID;

for(int iCount = 0; iCount < THREADCOUNT ; iCount++)
{
hThread[iCount] = CreateThread(NULL, 0, ThreadProc, 0,0, &aThreadID);
if( hThread[iCount] == NULL )
{
cout<<"CreateThread error: %d" << GetLastError() << endl;
return 1;
}
}

WaitForMultipleObjects(THREADCOUNT, hThread, TRUE, INFINITE);

// Close thread and semaphore handles
for(int i=0; i < THREADCOUNT; i++ )
CloseHandle(hThread[i]);

cout << MySingleton::getInstance().getCounter() << endl ;

CloseHandle(g_semaphore);
_getch();
return 0;
}

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
//DWORD result = WaitForSingleObject(g_semaphore,INFINITE);
//if(WAIT_OBJECT_0 == result)
MySingleton::getInstance().incrementCouner();
//ReleaseSemaphore(g_semaphore,1, NULL);
return TRUE;
}

这是我的单例实现类。

#include "StdAfx.h"
#include "MySingleton.h"

MySingleton* MySingleton::m_instance = NULL;
HANDLE MySingleton::m_hSem = CreateSemaphore(NULL, 1, 1, _T("MySingleton"));
HANDLE MySingleton::m_One = CreateSemaphore(NULL, 1, 1, _T("MyOne"));

MySingleton::MySingleton(void) : m_counter(0)
{
}

MySingleton::~MySingleton(void)
{
cout << "destructor" << endl;
CloseHandle(m_hSem);
CloseHandle(m_One);
}

MySingleton& MySingleton::getInstance()
{
DWORD result = WaitForSingleObject(m_hSem, INFINITE);

if(WAIT_OBJECT_0 == result)
{
if(m_instance == NULL)
{
cout << "creating" << endl;
m_instance = new MySingleton();
}
}
ReleaseSemaphore(m_hSem,1,NULL);
return *m_instance;
}

void MySingleton::setCouner(int iCount_in)
{
m_counter = iCount_in;
}
int MySingleton::getCounter()
{
return m_counter;
}

void MySingleton::incrementCouner()
{
DWORD result = WaitForSingleObject(m_One, INFINITE);
if(WAIT_OBJECT_0 == result)
m_counter++;
ReleaseSemaphore(m_One,1,NULL);
}

这是我的 .h 类。

#pragma once
#include <windows.h>
#include <iostream>
#include <conio.h>
using namespace std;

class MySingleton
{
private:
static HANDLE m_hSem, m_One;
HANDLE m_hCountSem;
static MySingleton* m_instance;
int m_counter;
MySingleton();
MySingleton(const MySingleton& obj_in);
MySingleton& operator=(const MySingleton& obj_in);
public:
~MySingleton(void);

static MySingleton& getInstance();
void setCouner(int iCount_in);
int getCounter();

void incrementCouner();
};

问题是计数器的最终值永远不会是 100。有人可以向我解释为什么以及我做错了什么。我无法理解这个问题。当我在创建每个线程之前在 main 中引休眠眠时,它工作正常。

最佳答案

问题是对 WaitForMultipleObjects 的调用最多处理 MAXIMUM_WAIT_OBJECTS,至少在 Visual Studio 2017 中是 64。

请注意您调用 WaitForMultipleObjects 以加入线程是如何返回 WAIT_FAILED 的。

为了等待更多的对象,according to the documentation :

To wait on more than MAXIMUM_WAIT_OBJECTS handles, use one of the following methods:

  • Create a thread to wait on MAXIMUM_WAIT_OBJECTS handles, then wait on that thread plus the other handles. Use this technique to break the handles into groups of MAXIMUM_WAIT_OBJECTS.
  • Call RegisterWaitForSingleObject to wait on each handle. A wait thread from the thread pool waits on MAXIMUM_WAIT_OBJECTS registered objects and assigns a worker thread after the object is signaled or the time-out interval expires.

关于c++ - 带有信号量的线程安全单例问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46023804/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com