使用临界段实现优化的进程间同步对象-原理和实现
2007-10-27 12:33
531 查看
2001年09月28日 10:12:00
使用临界段实现优化的进程间同步对象-原理和实现
by Jeffrey.Richter
vcbear 热情讲解
实现自己的同步对象?需要吗?
不需要吗?
...
只是跟你研究一下而已.
算了吧我只是个爱灌水的家伙,很久没有写代码了,闲来无事,灌灌水还不行吗?
1.概述:
在多进程的环境里,需要对线程进行同步.常用的同步对象有临界段(Critical Section),互斥量(Mutex),信号量(Semaphore),事件(Event)等,除了临界段,都是内核对象。
在同步技术中,临界段(Critical Section)是最容易掌握的,而且,和通过等待和释放内核态互斥对象实现同步的方式相比,临界段的速度明显胜出.但是临界段有一个缺陷,WIN32文档已经说明了临界段是不能跨进程的,就是说临界段不能用在多进程间的线程同步,只能用于单个进程内部的线程同步.
因为临界段只是一个很简单的数据结构体,在别的进程的进程空间里是无效的。就算是把它放到一个可以多进程共享的内存映象文件里,也还是无法工作.
有甚么方法可以跨进程的实现线程的高速同步吗?
2.原理和实现
2.1为什么临界段快? 是“真的”快吗?
确实,临界段要比其他的核心态同步对象要快,因为EnterCriticalSection和LeaveCriticalSection这两个函数从InterLockedXXX系列函数中得到不少好处(下面的代码演示了临界段是如何使用InterLockedXXX函数的)。InterLockedXXX系列函数完全运行于用户态空间,根本不需要从用户态到核心态
之间的切换。所以,进入和离开一个临界段一般只需要10个左右的CPU执行指令。而当调用WaitForSingleObject之流的函数时,因为使用了内核对象,线程被强制的在用户态和核心态之间变换。在x86处理器上,这种变换一般需要600个CPU指令。看到这里面的巨大差距了把。
话说回来,临界段是不是真正的“快”?实际上,临界段只在共享资源没有冲突的时候是快的。当一个线程试图进入正在被另外一个线程拥有的临界段,即发生竞争冲突时,临界段还是等价于一个event核心态对象,一样的需要耗时约600个CPU指令。事实上,因为这样的竞争情况相对一般的运行情况来说是很少的(除非人为),所以在大部分的时间里(没有竞争冲突的时候),临界段的使用根本不牵涉内核同步,所以是高速的,只需要10个CPU的指令。(bear说:明白了吧,纯属玩概率,Ms的小花招)
2.3进程边界怎么办?
“临界段等价于一个event核心态对象”是什么意思?
看看临界段结构的定义先
typedef struct _RTL_CRITICAL_SECTION {
PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
//
// The following three fields control entering and exiting the critical
// section for the resource
//
LONG LockCount;
LONG RecursionCount;
HANDLE OwningThread; // from the thread's ClientId-windows.h<
#include "Optex.h"
///////////////////////////////////////////////////////////////////////////////
BOOL COptex::CommonConstructor(PVOID pszName, BOOL fUnicode, DWORD dwSpinCount)
{
m_hevt = m_hfm = NULL;
m_pSharedInfo = NULL;
SYSTEM_INFO sinf;
GetSystemInfo(&sinf);
m_fUniprocessorHost = (sinf.dwNumberOfProcessors == 1);
char szNameA[100];
if (fUnicode) { // Convert Unicode name to ANSI
wsprintfA(szNameA, "%S", pszName);
pszName = (PVOID) szNameA;
}
char sz[100];
wsprintfA(sz, "JMR_Optex_Event_%s", pszName);
m_hevt = CreateEventA(NULL, FALSE, FALSE, sz);
if (m_hevt != NULL) {
wsprintfA(sz, "JMR_Optex_MMF_%s", pszName);
m_hfm = CreateFileMappingA(NULL, NULL, PAGE_READWRITE, 0, sizeof(*m_pSharedInfo), sz);
if (m_hfm != NULL) {
m_pSharedInfo = (PSHAREDINFO) MapViewOfFile(m_hfm, FILE_MAP_WRITE,
0, 0, 0);
// Note: SHAREDINFO's m_lLockCount, m_dwThreadId, and m_lRecurseCount
// members need to be initialized to 0. Fortunately, a new pagefile
// MMF sets all of its data to 0 when created. This saves us from
// some thread synchronization work.
if (m_pSharedInfo != NULL)
SetSpinCount(dwSpinCount);
}
}
return((m_hevt != NULL) && (m_hfm != NULL) && (m_pSharedInfo != NULL));
}
///////////////////////////////////////////////////////////////////////////////
COptex::~COptex() {
#ifdef _DEBUG
if (m_pSharedInfo-!--article end--<
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=3540
使用临界段实现优化的进程间同步对象-原理和实现
by Jeffrey.Richter
vcbear 热情讲解
实现自己的同步对象?需要吗?
不需要吗?
...
只是跟你研究一下而已.
算了吧我只是个爱灌水的家伙,很久没有写代码了,闲来无事,灌灌水还不行吗?
1.概述:
在多进程的环境里,需要对线程进行同步.常用的同步对象有临界段(Critical Section),互斥量(Mutex),信号量(Semaphore),事件(Event)等,除了临界段,都是内核对象。
在同步技术中,临界段(Critical Section)是最容易掌握的,而且,和通过等待和释放内核态互斥对象实现同步的方式相比,临界段的速度明显胜出.但是临界段有一个缺陷,WIN32文档已经说明了临界段是不能跨进程的,就是说临界段不能用在多进程间的线程同步,只能用于单个进程内部的线程同步.
因为临界段只是一个很简单的数据结构体,在别的进程的进程空间里是无效的。就算是把它放到一个可以多进程共享的内存映象文件里,也还是无法工作.
有甚么方法可以跨进程的实现线程的高速同步吗?
2.原理和实现
2.1为什么临界段快? 是“真的”快吗?
确实,临界段要比其他的核心态同步对象要快,因为EnterCriticalSection和LeaveCriticalSection这两个函数从InterLockedXXX系列函数中得到不少好处(下面的代码演示了临界段是如何使用InterLockedXXX函数的)。InterLockedXXX系列函数完全运行于用户态空间,根本不需要从用户态到核心态
之间的切换。所以,进入和离开一个临界段一般只需要10个左右的CPU执行指令。而当调用WaitForSingleObject之流的函数时,因为使用了内核对象,线程被强制的在用户态和核心态之间变换。在x86处理器上,这种变换一般需要600个CPU指令。看到这里面的巨大差距了把。
话说回来,临界段是不是真正的“快”?实际上,临界段只在共享资源没有冲突的时候是快的。当一个线程试图进入正在被另外一个线程拥有的临界段,即发生竞争冲突时,临界段还是等价于一个event核心态对象,一样的需要耗时约600个CPU指令。事实上,因为这样的竞争情况相对一般的运行情况来说是很少的(除非人为),所以在大部分的时间里(没有竞争冲突的时候),临界段的使用根本不牵涉内核同步,所以是高速的,只需要10个CPU的指令。(bear说:明白了吧,纯属玩概率,Ms的小花招)
2.3进程边界怎么办?
“临界段等价于一个event核心态对象”是什么意思?
看看临界段结构的定义先
typedef struct _RTL_CRITICAL_SECTION {
PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
//
// The following three fields control entering and exiting the critical
// section for the resource
//
LONG LockCount;
LONG RecursionCount;
HANDLE OwningThread; // from the thread's ClientId-windows.h<
#include "Optex.h"
///////////////////////////////////////////////////////////////////////////////
BOOL COptex::CommonConstructor(PVOID pszName, BOOL fUnicode, DWORD dwSpinCount)
{
m_hevt = m_hfm = NULL;
m_pSharedInfo = NULL;
SYSTEM_INFO sinf;
GetSystemInfo(&sinf);
m_fUniprocessorHost = (sinf.dwNumberOfProcessors == 1);
char szNameA[100];
if (fUnicode) { // Convert Unicode name to ANSI
wsprintfA(szNameA, "%S", pszName);
pszName = (PVOID) szNameA;
}
char sz[100];
wsprintfA(sz, "JMR_Optex_Event_%s", pszName);
m_hevt = CreateEventA(NULL, FALSE, FALSE, sz);
if (m_hevt != NULL) {
wsprintfA(sz, "JMR_Optex_MMF_%s", pszName);
m_hfm = CreateFileMappingA(NULL, NULL, PAGE_READWRITE, 0, sizeof(*m_pSharedInfo), sz);
if (m_hfm != NULL) {
m_pSharedInfo = (PSHAREDINFO) MapViewOfFile(m_hfm, FILE_MAP_WRITE,
0, 0, 0);
// Note: SHAREDINFO's m_lLockCount, m_dwThreadId, and m_lRecurseCount
// members need to be initialized to 0. Fortunately, a new pagefile
// MMF sets all of its data to 0 when created. This saves us from
// some thread synchronization work.
if (m_pSharedInfo != NULL)
SetSpinCount(dwSpinCount);
}
}
return((m_hevt != NULL) && (m_hfm != NULL) && (m_pSharedInfo != NULL));
}
///////////////////////////////////////////////////////////////////////////////
COptex::~COptex() {
#ifdef _DEBUG
if (m_pSharedInfo-!--article end--<
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=3540
相关文章推荐
- 使用临界段实现优化的进程间同步对象-原理和实现
- 使用临界段实现优化的进程间同步对象-原理和实现 (转)
- 使用临界段实现优化的进程间同步对象-原理和实现
- 使用临界段实现优化的进程间同步对象-原理和实现
- 使用临界段原理实现优化的进程间同步对象-原理和实现
- 使用临界段实现优化的进程间同步对象-原理和实现
- 使用临界段实现优化的进程间同步对象-原理和实现
- 使用临界段实现优化的进程间同步对象-原理和实现
- 使用临界段实现优化的进程间同步对象-原理和实现
- Dubbo原理实现之使用Javassist字节码结束构建代理对象
- C++使用临界区实现进程同步
- c#实现数据同步的方法(使用文件监控对象filesystemwatcher)
- Java多线程编程-(5)-使用Lock对象实现同步以及线程间通信
- 使用文件锁实现进程间同步
- Linux下通过共享内存进行进程间通信,进程间同步使用信号量来实现
- 共享内存多进程间通信,进程间同步使用信号量来实现
- jQuery的deferred对象使用详解——实现ajax同步请求数据
- 在C#使用文件监控对象FileSystemWatcher 实现数据同步
- 多线程 : 使用 wait 和 notify 实现进程间同步通信
- 使用共享实现两个进程之间的聊天-使用有名信号量实现同步