C++ 带有信号量的线程安全单例问题
我已经编写了一个简单的单例应用程序 下面是我的示例主类C++ 带有信号量的线程安全单例问题,c++,multithreading,semaphore,C++,Multithreading,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
// 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;
}
//ThreadsafeSingletonUsingSemaphore.cpp:定义控制台应用程序的入口点。
//
#包括“stdafx.h”
#包括
#包括
#包括“MySingleton.h”
使用名称空间std;
int i=0;
#定义THREADCOUNT 100
DWORD WINAPI ThreadProc(LPVOID LPRAM);
句柄g_信号量=NULL;
int _tmain(int argc,_TCHAR*argv[]
{
g_semaphore=CreateSemaphore(NULL,1,1,_T(“TreadOne”);
句柄hThread[THREADCOUNT];
德沃德·阿瑟雷迪德;
对于(int-iCount=0;iCount cout您不需要编写所有这些代码。实现线程安全单例的最简单方法是使用Scott Meyer的单例习惯用法:
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::互斥计数器\u保护;
Singleton(){}
公众:
单例(const Singleton&)=删除;
单例(单例&&)=删除;
单例&运算符=(常量单例&)=delete;
单例&运算符=(单例&&)=删除;
静态单例和实例(){
静态单态介子;
返回指令;
}
无效设置计数器(int newVal){
标准::独特的锁(计数器保护);
计数器=newVal;
}
void incrementCounter(){
标准::独特的锁(计数器保护);
++计数器;
}
int getCounter()常量{
标准::独特的锁(计数器保护);
返回计数器;
}
};
更简单的方法是为计数器成员变量使用一个类型。然后可以完全忽略互斥锁和锁保护。问题是对WaitForMultipleObjects
的调用最多可以处理最大等待对象,至少在Visual Studio 2017中是64个
请注意,调用WaitForMultipleObjects
加入线程如何返回WAIT\u失败
为了等待更多的对象,应该:
要等待多个最大\u wait\u对象句柄,请使用以下方法之一:
- 创建一个线程以等待最大\u wait\u对象句柄,然后等待该线程和其他句柄。使用此技术将句柄拆分为最大\u wait\u对象组
- 调用RegisterWaitForSingleObject以等待每个句柄。线程池中的等待线程等待已注册对象的最大等待时间,并在对象发出信号或超时间隔过期后分配工作线程
为什么不使用C++自己的线程功能,而不是Win32?@prv不编辑带答案的问题。在答案中发布更正的代码,而不是在问题上。如果有人解决了你的问题,请向上投票,并给他们打勾,如果他们帮助向上投票。允许自我回答;编辑问题使现有答案毫无意义。我相信我写单例是这个练习的一部分。谢谢你的回答。问题不在于单例。问题在于我在单例中的计数器。我希望在程序执行结束时,计数器值将与主线程计数相同,但不是。这是我无法理解的。@PrV,我更想回答您在问题标题中的问题。无论如何,我展示的代码是实现(线程安全)的惯用方法Singleton在C++中。对不起,我只是在学习。我知道我的代码可能是愚蠢的。我真的不理解这个线程安全的事情。再次抱歉。@ USER442,OP的SUNITLON确实包含一些数据,而您的数据不这样。您的线程对于单体创建是安全的,但如果包含任何数据,则不会是这样。需要访问后创建,这是我见过的每个单身汉都需要做的。你完全正确。非常感谢现在我明白了问题所在。再次非常感谢
#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();
};
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;
}
};