微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

与信号量单线程的问题

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

以下是我的示例主类

// 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,_T("TreadOne")); HANDLE hThread[THREADCOUNT]; DWORD aThreadID; for(int iCount = 0; iCount < THREADCOUNT ; iCount++) { hThread[iCount] = CreateThread(NULL,ThreadProc,&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,NULL); return TRUE; }

这是我的单例实现类。

#include "StdAfx.h" #include "MySingleton.h" MySingleton* MySingleton::m_instance = NULL; HANDLE MySingleton::m_hSem = CreateSemaphore(NULL,_T("MySingleton")); HANDLE MySingleton::m_One = CreateSemaphore(NULL,_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,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,NULL); }

这是我的课。

一般的信号量范围是多less?

如何终止正在等待信号量操作的线程

全局信号量忽略本地信号量

在Semaphore上设置访问权限?

在linux中的信号量和共享内存

#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.可以有人请解释我为什么,是什么,我做错了。我无法理解这个问题。 当我在创build每个线程之前在主要中引入睡眠时,它工作正常。

如何等待/阻塞,直到信号量值在Windows中达到0

Windows信号量对象的大小是多less?

有没有办法使一个线程从一个无限的信号量等待进程被杀死?

Windows中的进程间信号量

生产者 – 消费者实施

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

请注意,如何调用WaitForMultipleObjects来加入线程将返回WAIT_Failed

根据文件 ,为了等待更多的物体:

要等待多个MAXIMUM_WAIT_OBJECTS句柄,请使用以下方法之一:

创建一个线程来等待MAXIMUM_WAIT_OBJECTS句柄,然后等待该线程加上其他句柄。 使用这种技术将句柄分成MAXIMUM_WAIT_OBJECTS组。

调用RegisterWaitForSingleObject在每个句柄上等待。 线程池中的等待线程等待MAXIMUM_WAIT_OBJECTS注册对象,并在对象发出信号或超时间隔到期后分配工作线程。

你不需要编写所有的代码。 实现线程安全单例的最简单方法是使用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::atomic<int>类型作为counter成员变量。 那么互斥和锁守就完全可以省略了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐