- 浏览: 488951 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (185)
- job (15)
- linux/windows/unix/bash/shell (31)
- JAVA/J2EE/spring/hibernate/struts (30)
- VC/C++ (48)
- mysql/postgresql (6)
- php/jsp/asp/pear (1)
- FMS/flex/openlaszlo/red5/openmeetings (34)
- apache/tomcat/ftp/svn (6)
- xen/vm/Hadoop/cloudcompute (6)
- visual studio/eclipse/zendstudi/ant (8)
- others (1)
- windows异常处理 __try __except (1)
- (1)
- matlab (4)
- android (0)
最新评论
-
hongzhounlfd:
很透彻,很详细
依赖注入和控制反转 -
jefferyqjy:
谢谢~言简意赅~很明了!
依赖注入和控制反转 -
elderbrother:
太好了,谢谢
依赖注入和控制反转 -
east_zyd_zhao:
终于搞明白了
依赖注入和控制反转 -
Dremeng:
完美,一看就懂理解透彻
依赖注入和控制反转
Using Event Objects
使用事件对象
Applications use event objects in a number of situations to notify a waiting thread of the occurrence of an event. For example, overlapped I/O operations on files, named pipes, and communications devices use an event object to signal their completion. For more information about the use of event objects in overlapped I/O operations, see Synchronization and Overlapped Input and Output.
应用程序使用事件对象来通知等待线程事件的发生,常用语IO操作中。
In the following example, an application uses event objects to prevent several threads from reading from a shared memory buffer while a master thread is writing to that buffer. First, the master thread uses the CreateEvent function to create a manual-reset event object. The master thread sets the event object to nonsignaled when it is writing to the buffer and then resets the object to signaled when it has finished writing. Then it creates several reader threads and an auto-reset event object for each thread. Each reader thread sets its event object to signaled when it is not reading from the buffer.
//宏定义
#define NUMTHREADS 4
HANDLE hGlobalWriteEvent;
HANDLE hReadEvents[NUMTHREADS];
//创建事件和线程
void CreateEventsAndThreads(void)
{
HANDLE hThread;
DWORD i, IDThread;
//创建人工重置的事件对象,当主线程在写的时候设置为非信号状态。
// Create a manual-reset event object. The master thread sets
// this to nonsignaled when it writes to the shared buffer.
//写事件对象
hGlobalWriteEvent = CreateEvent(
NULL, // default security attributes
TRUE, // manual-reset event
TRUE, // initial state is signaled
"WriteEvent" // object name
);
//判断创建是否成功,不成功就直接返回
if (hGlobalWriteEvent == NULL)
{
printf("CreateEvent failed (%d)\n", GetLastError());
return;
}
//创建多线程和每一个线程的自动设置事件对象。当每一个线程不在读的时候设置它为信号状态
// Create multiple threads and an auto-reset event object
// for each thread. Each thread sets its event object to
// signaled when it is not reading from the shared buffer.
//创建多线程的事件对象
for(i = 0; i < NUMTHREADS; i++)
{
// Create the auto-reset event.
hReadEvents[i] = CreateEvent(
NULL, // no security attributes
FALSE, // auto-reset event
TRUE, // initial state is signaled
NULL); // object not named
if (hReadEvents[i] == NULL)
{
printf("CreateEvent failed (%d)\n", GetLastError());
return;
}
//创建多线程
hThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) ThreadFunction,
&hReadEvents[i], // pass event handle
0, &IDThread);
if (hThread == NULL)
{
printf("CreateThread failed (%d)\n", GetLastError());
return;
}
}
}
Before the master thread writes to the shared buffer, it uses the ResetEvent function to set the state of hGlobalWriteEvent (an application-defined global variable) to nonsignaled. This blocks the reader threads from starting a read operation. The master then uses the WaitForMultipleObjects function to wait for all reader threads to finish any current read operations. When WaitForMultipleObjects returns, the master thread can safely write to the buffer. After it has finished, it sets hGlobalWriteEvent and all the reader-thread events to signaled, enabling the reader threads to resume their read operations.
//写的函数
VOID WriteToBuffer(VOID)
{
DWORD dwWaitResult, i;
// Reset hGlobalWriteEvent to nonsignaled, to block readers.
//设置写线程事件对象为非信号状态,阻止其他的线程读取数据
if (! ResetEvent(hGlobalWriteEvent) )
{
printf("ResetEvent failed (%d)\n", GetLastError());
return;
}
//
// Wait for all reading threads to finish reading.
//等待所有的读线程完成,返回一个某是信号状态的读线程的索引
dwWaitResult = WaitForMultipleObjects(
NUMTHREADS, // number of handles in array
hReadEvents, // array of read-event handles
TRUE, // wait until all are signaled
INFINITE); // indefinite wait
//判读是否所有的读线程都是信号状态(即所有的读操作都结束了,可以写操作了)
switch (dwWaitResult)
{
// All read-event objects were signaled.
case WAIT_OBJECT_0:
// Write to the shared buffer.
break;
// An error occurred.
default:
printf("Wait error: %d\n", GetLastError());
ExitProcess(0);
}
//写完后设置写事件为信号状态,通知其他的读线程可以读操作了
// Set hGlobalWriteEvent to signaled.
//设置写事件信号状态不成功就返回
if (! SetEvent(hGlobalWriteEvent) )
{
printf("SetEvent failed (%d)\n", GetLastError());
return;
}
//设置所有的读进程为信号状态,即初始化所有的读操作事件信号状态,防止读操作之前发生其他错误。
// Set all read events to signaled.
for(i = 0; i < NUMTHREADS; i++)
if (! SetEvent(hReadEvents[i]) )
{
printf("SetEvent failed (%d)\n", GetLastError());
return;
}
}
Before starting a read operation, each reader thread uses WaitForMultipleObjects to wait for the application-defined global variable hGlobalWriteEvent and its own read event to be signaled. When WaitForMultipleObjects returns, the reader thread's auto-reset event has been reset to nonsignaled. This blocks the master thread from writing to the buffer until the reader thread uses the SetEvent function to set the event's state back to signaled.
//线程主函数
VOID ThreadFunction(LPVOID lpParam)
{
//等待结果字段
DWORD dwWaitResult;
//两个事件对象
HANDLE hEvents[2];
//
hEvents[0] = *(HANDLE*)lpParam; // thread's read event
hEvents[1] = hGlobalWriteEvent;
//等待多线程
dwWaitResult = WaitForMultipleObjects(
2, // number of handles in array
hEvents, // array of event handles
TRUE, // wait till all are signaled
INFINITE); // indefinite wait
switch (dwWaitResult)
{
// Both event objects were signaled.
case WAIT_OBJECT_0:
// Read from the shared buffer.
break;
// An error occurred.
default:
printf("Wait error: %d\n", GetLastError());
ExitThread(0);
}
// Set the read event to signaled.
if (! SetEvent(hEvents[0]) )
{
printf("SetEvent failed (%d)\n", GetLastError());
return;
}
}
使用事件对象
Applications use event objects in a number of situations to notify a waiting thread of the occurrence of an event. For example, overlapped I/O operations on files, named pipes, and communications devices use an event object to signal their completion. For more information about the use of event objects in overlapped I/O operations, see Synchronization and Overlapped Input and Output.
应用程序使用事件对象来通知等待线程事件的发生,常用语IO操作中。
In the following example, an application uses event objects to prevent several threads from reading from a shared memory buffer while a master thread is writing to that buffer. First, the master thread uses the CreateEvent function to create a manual-reset event object. The master thread sets the event object to nonsignaled when it is writing to the buffer and then resets the object to signaled when it has finished writing. Then it creates several reader threads and an auto-reset event object for each thread. Each reader thread sets its event object to signaled when it is not reading from the buffer.
//宏定义
#define NUMTHREADS 4
HANDLE hGlobalWriteEvent;
HANDLE hReadEvents[NUMTHREADS];
//创建事件和线程
void CreateEventsAndThreads(void)
{
HANDLE hThread;
DWORD i, IDThread;
//创建人工重置的事件对象,当主线程在写的时候设置为非信号状态。
// Create a manual-reset event object. The master thread sets
// this to nonsignaled when it writes to the shared buffer.
//写事件对象
hGlobalWriteEvent = CreateEvent(
NULL, // default security attributes
TRUE, // manual-reset event
TRUE, // initial state is signaled
"WriteEvent" // object name
);
//判断创建是否成功,不成功就直接返回
if (hGlobalWriteEvent == NULL)
{
printf("CreateEvent failed (%d)\n", GetLastError());
return;
}
//创建多线程和每一个线程的自动设置事件对象。当每一个线程不在读的时候设置它为信号状态
// Create multiple threads and an auto-reset event object
// for each thread. Each thread sets its event object to
// signaled when it is not reading from the shared buffer.
//创建多线程的事件对象
for(i = 0; i < NUMTHREADS; i++)
{
// Create the auto-reset event.
hReadEvents[i] = CreateEvent(
NULL, // no security attributes
FALSE, // auto-reset event
TRUE, // initial state is signaled
NULL); // object not named
if (hReadEvents[i] == NULL)
{
printf("CreateEvent failed (%d)\n", GetLastError());
return;
}
//创建多线程
hThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) ThreadFunction,
&hReadEvents[i], // pass event handle
0, &IDThread);
if (hThread == NULL)
{
printf("CreateThread failed (%d)\n", GetLastError());
return;
}
}
}
Before the master thread writes to the shared buffer, it uses the ResetEvent function to set the state of hGlobalWriteEvent (an application-defined global variable) to nonsignaled. This blocks the reader threads from starting a read operation. The master then uses the WaitForMultipleObjects function to wait for all reader threads to finish any current read operations. When WaitForMultipleObjects returns, the master thread can safely write to the buffer. After it has finished, it sets hGlobalWriteEvent and all the reader-thread events to signaled, enabling the reader threads to resume their read operations.
//写的函数
VOID WriteToBuffer(VOID)
{
DWORD dwWaitResult, i;
// Reset hGlobalWriteEvent to nonsignaled, to block readers.
//设置写线程事件对象为非信号状态,阻止其他的线程读取数据
if (! ResetEvent(hGlobalWriteEvent) )
{
printf("ResetEvent failed (%d)\n", GetLastError());
return;
}
//
// Wait for all reading threads to finish reading.
//等待所有的读线程完成,返回一个某是信号状态的读线程的索引
dwWaitResult = WaitForMultipleObjects(
NUMTHREADS, // number of handles in array
hReadEvents, // array of read-event handles
TRUE, // wait until all are signaled
INFINITE); // indefinite wait
//判读是否所有的读线程都是信号状态(即所有的读操作都结束了,可以写操作了)
switch (dwWaitResult)
{
// All read-event objects were signaled.
case WAIT_OBJECT_0:
// Write to the shared buffer.
break;
// An error occurred.
default:
printf("Wait error: %d\n", GetLastError());
ExitProcess(0);
}
//写完后设置写事件为信号状态,通知其他的读线程可以读操作了
// Set hGlobalWriteEvent to signaled.
//设置写事件信号状态不成功就返回
if (! SetEvent(hGlobalWriteEvent) )
{
printf("SetEvent failed (%d)\n", GetLastError());
return;
}
//设置所有的读进程为信号状态,即初始化所有的读操作事件信号状态,防止读操作之前发生其他错误。
// Set all read events to signaled.
for(i = 0; i < NUMTHREADS; i++)
if (! SetEvent(hReadEvents[i]) )
{
printf("SetEvent failed (%d)\n", GetLastError());
return;
}
}
Before starting a read operation, each reader thread uses WaitForMultipleObjects to wait for the application-defined global variable hGlobalWriteEvent and its own read event to be signaled. When WaitForMultipleObjects returns, the reader thread's auto-reset event has been reset to nonsignaled. This blocks the master thread from writing to the buffer until the reader thread uses the SetEvent function to set the event's state back to signaled.
//线程主函数
VOID ThreadFunction(LPVOID lpParam)
{
//等待结果字段
DWORD dwWaitResult;
//两个事件对象
HANDLE hEvents[2];
//
hEvents[0] = *(HANDLE*)lpParam; // thread's read event
hEvents[1] = hGlobalWriteEvent;
//等待多线程
dwWaitResult = WaitForMultipleObjects(
2, // number of handles in array
hEvents, // array of event handles
TRUE, // wait till all are signaled
INFINITE); // indefinite wait
switch (dwWaitResult)
{
// Both event objects were signaled.
case WAIT_OBJECT_0:
// Read from the shared buffer.
break;
// An error occurred.
default:
printf("Wait error: %d\n", GetLastError());
ExitThread(0);
}
// Set the read event to signaled.
if (! SetEvent(hEvents[0]) )
{
printf("SetEvent failed (%d)\n", GetLastError());
return;
}
}
发表评论
-
C++STL轻松导学(2)
2011-09-27 17:02 12732.2.2 第二版:工业时代- ... -
C++ STL轻松导学
2011-09-27 16:59 1130作为C++标准不可缺少的 ... -
Chapter 6 Exceptions(JAVA EXCEPTION IN NATIVE CODE)
2011-09-26 09:53 1456Contents | Prev | Next | Index ... -
JNI编程中如何传递参数和返回值。
2011-09-14 17:51 1754首先要强调的是,native方法不但可以传递Java的基本类型 ... -
Windows Mobile与Android应用开发对比
2011-09-06 11:44 1235Windows Mobile在经历过最初的Wince系列,po ... -
android和JNI经典blog.doc
2011-09-01 15:29 1703Android JNI调用 2011-02-24 1 ... -
定义VC 消息映射函数小结
2011-08-21 22:15 1281定义VC 消息映射函数小 ... -
VC++多线程调用webservice实例
2011-08-21 12:04 1543一、开始多线程 1.开始 ... -
多线程同步机制(Vc++)
2011-08-21 09:46 1697Synchronizing Execution of Mult ... -
如何结束线程VC++
2011-08-21 09:20 2749Terminating a Thread Terminati ... -
VS2005使用多字节字符集问题
2011-08-03 13:27 20381>------ 已启动生成: 项目: psgdatat ... -
matlab的作图函数(二维) 星号,点号 颜色
2011-07-27 14:57 9918zz matlab的作图函数(二维 ... -
android 调用C++的so
2011-07-08 18:36 4328第一步:开发环境的安 ... -
windows异常处理__try__except
2011-07-07 14:24 1940try-except用法 try except是win ... -
Java中的一个byte
2011-06-30 14:34 976Java中的一个byte,其范围是-128~127的,而Int ... -
NDK中char*如何转换成jstring
2011-06-30 13:05 1836JNIEXPORT jstring JNICALLJava_T ... -
CFileDialog多选文件时的最大数量
2011-06-25 20:29 2217system("explorer d:\我的 ... -
C++信号处理编程风格规范
2011-06-24 10:07 21241.背景: C++做数字信号处理很普遍,如何 ... -
C++如何获取系统时间
2011-06-22 11:31 623//方案— 优点:仅使用C标准库;缺点:只能精确到秒级 #in ... -
C++编码中减少内存缺陷的方法和工具
2011-06-14 10:22 1157C++编码中减少内存缺陷的方法和工具 编程技术 ...
相关推荐
线程之间通过事件对象通讯,vc技术内幕11章例子
详解介绍了事件内核对象的在多线程编程中的使用。很不错的哦,呵呵,多多指教,
《C++面向对象多线程编程》共分13章,全面讲解构建多线程架构与增量多线程编程...第11章讨论C++对象在多线程环境中的行为和交互方式。第12章简单介绍多线程应用程序的测试技术。第13章对全书内容进行扼要地回顾与思考。
vc++ 多线程教程---线程通信--利用事件对象,线程同步--使用信号量,线程同步--使用互斥量,线程同步--使用临界区
C++ 面向对象多线程编程.4/4
C++面向对象多线程编程,介绍c++的多线程编程
c++ 面向对象多线程编程
如何避免这种竞态条件是 C++ 多线程编程面临的基本问题,可以借助 boost 的 shared_ptr 和 weak_ptr 完美解决。这也是实现线程安全的 Observer 模式的必备技术。 本文源自我在 2009 年 12 月上海 C++ 技术大会的一场...
C++ 面向对象多线程编程 共四部分
C++ 面向对象多线程编程.pdf 。
面向对象的多线程编程,进程必须至少占有一个线程,所以线程是描述进程内的执行,正是线程负责执行包含在进程的地址空间中的代码。
不精通线程、不擅长对多线程进行管理,就不可能在当今多CPU多核心的年代写出优秀的程序代码,软件的性能将会大打折扣。本文及其示例代码,诠释System.Classes.pas中的(多)线程 和System.SyncObjs.pas (深入应用...
c++编程 C++面向对象多线程编程 c++标准程序库
[Delphi]多线程编程(13)多线程同步之Event(事件对象).pdf
c++高级编程 C++面向对象多线程编程 c++标准程序库.pdf