一个简单的iocp有关问题,请大家进来看看
一个简单的iocp问题,请大家进来看看
WriteFile成功50次。 for循环158次。 2个线程GetQueuedCompletionStatus共计76次。 文件写入正常,共写入DWORD类型从1~50.
大家凑合看啊,我用手机发的编辑不了啊!
我是想问writefile函数一共执行了158次,成功了50次,其他都是错误代码997,io未决。我的理解
两个线程应该一共执行50次才对啊,为什么执行了76次??而且我看写入的文件也确实是1~50。请大神
给我讲讲啊!是我完成端口用错了么?如果用错了请问怎么修改?谢谢啊!!
------解决方案--------------------
IOCP的优势是用来管理多个IO操作和不阻塞调用IO的线程
而不是用来提高IO的读写效率的
而是说提高线程的利用率
IO读写是低速操作,总线就只有这么一条,开多少个线程来做并不会提高性能,
,多线程之间会竞争
WSA_IO_PENDING说明还有一次或多次IO在排队等待完成
WriteFile和GetQueuedCompletionStatus的次数不一样的原因可能是:
例如,WriteFile写50字节,而GetQueuedCompletionStatus返回2次,30字节和20字节
你可以观察一下 len 的值
- C/C++ code
// IOCPtest1.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <Windows.h> HANDLE myiocp; HANDLE myfile; OVERLAPPED myol_w = {0}; HANDLE hh; DWORD lend; DWORD wcount = 1; DWORD WINAPI th(PVOID lp) { printf("进入线程1\n"); DWORD len; ULONG_PTR completionKey; OVERLAPPED *op; while(1) { GetQueuedCompletionStatus(myiocp,&len,&completionKey,&op,INFINITE); if (completionKey == 3) { break; } switch(completionKey) { case 1: //if (WaitForSingleObject(myol_w.hEvent,0) == WAIT_OBJECT_0) if (WaitForSingleObject(op->hEvent,0) == WAIT_OBJECT_0) { completionKey = 0; FlushFileBuffers(myfile); printf("线程中1——写入完成%u\n",wcount++); } //free(op); break; default: printf("线程中1——完成键无数据\n"); break; } Sleep(1); } printf("线程中1——线程退出\n"); return 0; } DWORD WINAPI th1(PVOID lp) { printf("进入线程2\n"); DWORD len; ULONG_PTR completionKey; OVERLAPPED *op; while(1) { GetQueuedCompletionStatus(myiocp,&len,&completionKey,&op,INFINITE); if (completionKey == 3) { break; } switch(completionKey) { case 1: //if (WaitForSingleObject(myol_w.hEvent,0) == WAIT_OBJECT_0) if (WaitForSingleObject(op->hEvent,0) == WAIT_OBJECT_0) { completionKey = 0; FlushFileBuffers(myfile); printf("线程中2——写入完成%u\n",wcount++); } //free(op); break; default: printf("线程中2——完成键无数据\n"); break; } Sleep(1); } printf("线程中2——线程退出\n"); return 0; } int _tmain(int argc, _TCHAR* argv[]) { //创建IOCP,前三个参数固定,第4个参数为要使用的线程数量,一般为CPU数量。0为 使用系统默认值. myiocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0); HANDLE myt = CreateThread(NULL,0,th,NULL,0,NULL); CloseHandle(myt); HANDLE myt1 = CreateThread(NULL,0,th1,NULL,0,NULL); CloseHandle(myt1); hh = CreateEvent(NULL,false,false,NULL); myol_w.hEvent = hh; myfile = CreateFile("data.dat",GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMA L | FILE_FLAG_OVERLAPPED,NULL); if (myfile == INVALID_HANDLE_VALUE) { printf("创建文件失败"); system("pause"); } LARGE_INTEGER len; len.QuadPart = 1024*1024; SetFilePointerEx(myfile,len,NULL,FILE_BEGIN); SetEndOfFile(myfile); SetFilePointerEx(myfile,len,NULL,FILE_BEGIN); lend = 0; DWORD for_count = 0; system("pause"); myol_w.Offset = 0;//偏移量 低位。 myol_w.OffsetHigh = 0;//偏移量 高位。 for(int c = 1; c <= 50; ) { //与设备句柄关联,参数1为设备handle,参数2为一个新的iocp的句柄,参 数3为一个完成键可以是任何值,参数4默认0即可. //注意:使用完成键来让线程识别是何种操作时,每次 CreateIoCompletionPort时第一个参数必须不能相同,不然 //GetQueuedCompletionStatus得来的完成键只是第一个进入队列的操 作。 //注:IOCP投递一个IO时是按照先进先出的原则。 //而线程中谁后GetQueuedCompletionStatus却优先调用,从而有可能先 GetQueuedCompletionStatus的线程永远也不会被调用. CreateIoCompletionPort(myfile,myiocp,1,0); for_count++; //if (WriteFile(myfile,wstr,16,&lend,&myol_w)) if (WriteFile(myfile,&c,4,&lend,&myol_w)) { c++; myol_w.Offset += 4;//偏移量 低位。 myol_w.OffsetHigh = 0;//偏移量 高位。 } Sleep(10); } printf("等待时间完成。。。。。\n\n"); CloseHandle(myfile); printf("关闭线程\n"); //关闭一个完成端口需要调用PostQueuedCompletionStatus,参数1~4可以为规定 类型的任何值,然后在 //GetQueuedCompletionStatus后判断,从而退出。本例是使用完成键来判断退出. PostQueuedCompletionStatus(myiocp,0,3,0); PostQueuedCompletionStatus(myiocp,0,3,0); system("pause"); return 0; }
WriteFile成功50次。 for循环158次。 2个线程GetQueuedCompletionStatus共计76次。 文件写入正常,共写入DWORD类型从1~50.
大家凑合看啊,我用手机发的编辑不了啊!
我是想问writefile函数一共执行了158次,成功了50次,其他都是错误代码997,io未决。我的理解
两个线程应该一共执行50次才对啊,为什么执行了76次??而且我看写入的文件也确实是1~50。请大神
给我讲讲啊!是我完成端口用错了么?如果用错了请问怎么修改?谢谢啊!!
------解决方案--------------------
IOCP的优势是用来管理多个IO操作和不阻塞调用IO的线程
而不是用来提高IO的读写效率的
而是说提高线程的利用率
IO读写是低速操作,总线就只有这么一条,开多少个线程来做并不会提高性能,
,多线程之间会竞争
WSA_IO_PENDING说明还有一次或多次IO在排队等待完成
WriteFile和GetQueuedCompletionStatus的次数不一样的原因可能是:
例如,WriteFile写50字节,而GetQueuedCompletionStatus返回2次,30字节和20字节
你可以观察一下 len 的值