带有信号的ThreadSafe Singleton的问题
issue with Threadsafe singleton with semaphore
我写了一个简单的单例应用程序。
以下是我的样本主要类
// 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;
}
这是我的Singleton实施类。
#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。当我在创建每个线程之前在主机中引入睡眠时,它可以正常工作。
问题是呼叫WaitForMultipleObjects
的MAXIMUM_WAIT_OBJECTS
处理至少在Visual Studio 2017中为64。
请注意如何致电WaitForMultipleObjects
加入线程返回WAIT_FAILED
。
为了等待更多对象,应该根据文档:
等待超过最大_wait_objects手柄,使用以下方法之一:
- 创建一个线程以等待最大_wait_objects手柄,然后在该线程以及另一个手柄上等待。使用此技术将手柄分解为最大_wait_objects。
- 呼叫registerwaitforsingleobject在每个句柄上等待。线程池中的等待线程在最大_wait_objects注册的对象上等待,并在对象发出信号或超时间隔后分配工作线程。
您不需要编写所有代码。实现线程安全单位的最简单方法是使用Scott Meyer的Singleton Idiom:
class Singleton {
int counter;
mutable std::mutex counter_guard;
Singleton() {}
public:
Singleton(const Singleton&) = delete;
Singleton(Singleton&&) = delete;
Singleton& operator=(const Singleton&) = delete;
Singleton& operator=(Singleton&&) = delete;
static Singleton& instance() {
static Singleton theInstance;
return theInstance;
}
void setCounter(int newVal) {
std::unique_lock<std::mutex> lock(counter_guard);
counter = newVal;
}
void incrementCounter() {
std::unique_lock<std::mutex> lock(counter_guard);
++counter;
}
int getCounter() const {
std::unique_lock<std::mutex> lock(counter_guard);
return counter;
}
};
一种更简单的方法是将std::atomic<int>
类型用于counter
成员变量。然后,完全可以省略Mutex和Lock Guards。
相关文章:
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- C++ Singleton - Prevent ::instance() to variable
- 一个关于在C++中重载布尔运算符的问题
- 带有信号的ThreadSafe Singleton的问题
- singleton的延迟初始化问题
- C++Singleton实现-静态问题
- 此singleton(Not类)的问题
- 这个Singleton实现有什么问题