异步过程调用(Asynchronous Procedure Call)
2015-07-25 18:43
417 查看
/*Demonstrates how to use APC's(asynchronous procedure
calls)instread of signaled objects to service multiple
outstanding overlapped operations on a file*/
#define WIN32_LEAN_AND_MEAN
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include "MtVerify.h"
//constants
#define MAX_REQUESTS 5
#define READ_SIZE 512
#define MAX_TRY_COUNT 5
//Function prototypes
void CheckOsVersion();
int QueueRequest(int nIndex, DWORD dwLocation, DWORD dwAmount);
//Global variables
//Need a single event object so we know when all I/O is finished
HANDLE ghEvent;
//Keep track of each individual I/O operation
OVERLAPPED gOverlapped[MAX_REQUESTS];
//Handle to the file of interest
HANDLE ghFile;
//Need a place to put all this data
char gBuffers[MAX_REQUESTS][READ_SIZE];
int nCompletionCount;
/* I/O Completion routine gets called
when app is alertable(in WaitForSingleObjectEx)
and an overlapped I/O operation has completed.
*/
VOID WINAPI FileIOCompletionRoutine(DWORD dwErrorCode,
DWORD dwNumberOfBytesTransfered,
LPOVERLAPPED lpvOverlapped)
{
//The event handle is really the user defined data
int nIndex = (int)(lpvOverlapped->hEvent);
printf("Read #%d returned %d.%d bytes were read.\n", nIndex, dwErrorCode, dwNumberOfBytesTransfered);
if (++nCompletionCount == MAX_REQUESTS)
{
SetEvent(ghEvent);//cause the wait to terminate
}
}
int main()
{
int i;
char szPath[MAX_PATH];
CheckOsVersion();
//NEED to know when to stop
MTVERIFY(ghEvent = CreateEvent(NULL, TRUE,
FALSE, NULL));
GetWindowsDirectory(LPWSTR(szPath), sizeof(szPath));
strcat(szPath, "\\WINHLP32.EXE");
//open the file for overlapped reads
ghFile = CreateFile(LPCWSTR(szPath), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL);
if (ghFile == INVALID_HANDLE_VALUE)
{
printf("Could not open %s \n", szPath);
return -1;
}
//Queue up a few requests
for (i = 0; i < MAX_REQUESTS; i++)
{
//Read some bytes every few K
QueueRequest(i, i * 16384, READ_SIZE);
}
printf("QUEUED!!\n");
//wait for all the operations to complete.
for (;;)
{
DWORD rc;
rc = WaitForSingleObjectEx(ghEvent, INFINITE, TRUE);
if (rc == WAIT_OBJECT_0)
break;
MTVERIFY(rc == WAIT_IO_COMPLETION);
}
CloseHandle(ghFile);
return EXIT_SUCCESS;
}
/*call readfileEx to start an overlapped request
make sure we handle errors that are recoverable
*/
int QueueRequest(int nIndex, DWORD dwLocation, DWORD dwAmount)
{
int i;
BOOL rc;
DWORD err;
gOverlapped[nIndex].hEvent = (HANDLE)nIndex;
gOverlapped[nIndex].Offset = dwLocation;
for (i = 0; i < MAX_TRY_COUNT; i++)
{
rc = ReadFileEx(ghFile,
gBuffers[nIndex],
dwAmount, &gOverlapped[nIndex],
FileIOCompletionRoutine);
//Handle success
if (rc)
{
//asynchronous i/o is still in progress
printf("Read #%d queued for overlapped I/O.\n");
return TRUE;
}
err = GetLastError();
//Handle recoverable error
if (err == ERROR_INVALID_USER_BUFFER
|| err == ERROR_NOT_ENOUGH_QUOTA
|| err == ERROR_NOT_ENOUGH_MEMORY)
{
Sleep(50);//wait around and try later
continue;
}
//Give up on fatal error.
break;
}
printf("ReadFileEx failed.\n");
return -1;
}
//make sure we are running under an operating
//system that supports overlapped I/O to files/
void CheckOsVersion()
{
OSVERSIONINFO ver;
BOOL bResult;
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
bResult = GetVersionEx((LPOSVERSIONINFO)&ver);
if ((!bResult) || (ver.dwPlatformId != VER_PLATFORM_WIN32_NT))
{
fprintf(stderr, "OpByAPC must be run under Windows NT.\n");
exit(EXIT_FAILURE);
}
}
相关文章推荐
- 二分搜索 POJ 3273 Monthly Expense
- static关键字学习总结
- stm32定时器输入捕获pwm
- Android高效布局
- ResourceDictionary.MergedDictionaries 属性wpf
- ZOJ3527
- 如何修改Android系统的版本号
- Distance Queries
- 数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历
- ZOJ - 2186 Keep on Truckin'
- mysql jdbc连接
- linux_shell_轮询触发启动脚本
- Android获得Manifest在<meta-data>元件的值
- Storm介绍(一)
- 关于SpringMVC注解的一些补充说明
- Android四大组件之BroadcastReceveier
- Introduction to gaussian filter 高斯滤波器
- html DOCTYPE声明详解
- 二分搜索 POJ 1064 Cable master
- SpringMvc自定义拦截器