windows下怎么实现文件异步IO???

ReMeppo 2012-09-21 04:26:40
最近在windows下写点程序 , 遇到了这个纠结的问题, 不像Unix, 找个函数纠结啊~~~ 下面是2个程序的代码 一个程序写, 一个程序读, 为啥读的程序老是要等到写的程序closeHandle(h_file)后, 才能CreateFile成功呢。。。

跪求进程间文件异步 IO的方法~~


//写进程
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

struct abc{
int a;
char b[20];
long c;
char d[128];
};

int main()
{
char *name = "D:\\MyProjects\\a.txt";
int i=0;
struct abc m_var;
DWORD num;
HANDLE h_file;

h_file = CreateFile( name, // 指向文件名的指针
GENERIC_WRITE, // 访问模式(写 / 读)
FILE_SHARE_READ, // 共享模式
NULL, // 指向安全属性的指针
OPEN_ALWAYS, // 如何创建
FILE_ATTRIBUTE_NORMAL, // 文件属性
NULL // 用于复制文件句柄
);

SetFilePointer(h_file,0,0,FILE_END); //定位到文件末

for (i=0; i<100000; i++) { //这个数加大, 在循环运行时 另个进程CreateFile失败...
memset(&m_var, 0, sizeof(m_var));
m_var.a = i;
strcpy(m_var.b, "abcdefghijklmopq");
m_var.c = i*10;
strcpy(m_var.d, "0123456789");
WriteFile(h_file, &m_var, sizeof(m_var), &num, NULL);
}

Sleep(5*1000); //到这sleep时,另一个进程CreateFile还是失败

CloseHandle(h_file); //好像唯独close后 读进程运行 才能成功
return 0;
}


//读进程
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

struct abc{
int a;
char b[20];
long c;
char d[128];
};

int main()
{
char *name = "D:\\MyProjects\\a.txt";
int i=0;
struct abc m_var;
DWORD num;

HANDLE h_file;

h_file = CreateFile(name, // 指向文件名的指针
GENERIC_READ, // 访问模式(写 / 读)
0, // 共享模式
NULL, // 指向安全属性的指针
OPEN_ALWAYS, // 如何创建
FILE_ATTRIBUTE_NORMAL, // 文件属性
NULL // 用于复制文件句柄
);

if (h_file == INVALID_HANDLE_VALUE) {
printf("Create h_file error!\n"); //每次失败都是失败在这
return -1;
}

SetFilePointer(h_file,0,0,FILE_BEGIN);
for (i=0; i<100; i++) {
memset(&m_var, 0, sizeof(m_var));
ReadFile(h_file, &m_var, sizeof(m_var), &num, NULL);
printf("i=%d\nm_var.a:%d\nm_var.b:%s\nm_var.c:%ld\nm_var.d:%s\n\n", i, m_var.a, m_var.b, m_var.c, m_var.d);
}

CloseHandle(h_file);
return 0;
}
...全文
1858 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
神-气 2013-11-18
  • 打赏
  • 举报
回复
这和异步有什么关系...
xiaoRainie 2012-09-30
  • 打赏
  • 举报
回复
使用内存映射啊,说windows的都是自己水平不过关吧,我觉得windows对于同步原语和IPC要比Linux下先进啊
赵4老师 2012-09-28
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 的回复:]

引用 21 楼 的回复:

引用 20 楼 的回复:

引用 19 楼 的回复:

_fsopen

非常感谢, 用CFILE 得换成C++, 现在项目都是用的C,没办法改!!!
用_fsopen可以同时打开 一个读一个写了。。。
不过 不知道有没有用于FILE* 的读写锁呢....


有啊,我之前的参考链接里。不光是读写,只要共享资源的情况都可以。

……
跟需求有点不同哦.. 互斥量是进程间完全互斥了.. 信号灯只记数量 也不能区分进程操作是读还是写... 我是想 有木有像Unix一样 我单独锁 我将要写的那块区域, 其他区域不锁住! 其他进程仍可以读!
[/Quote]
_locking
Locks or unlocks bytes of a file.

int _locking( int handle, int mode, long nbytes );

Routine Required Header Optional Headers Compatibility
_locking <io.h> and <sys/locking.h> <errno.h> Win 95, Win NT


For additional compatibility information, see Compatibility in the Introduction.

Libraries

LIBC.LIB Single thread static library, retail version
LIBCMT.LIB Multithread static library, retail version
MSVCRT.LIB Import library for MSVCRT.DLL, retail version


Return Value

_locking returns 0 if successful. A return value of –1 indicates failure, in which case errno is set to one of the following values:

EACCES

Locking violation (file already locked or unlocked).

EBADF

Invalid file handle.

EDEADLOCK

Locking violation. Returned when the _LK_LOCK or _LK_RLCK flag is specified and the file cannot be locked after 10 attempts.

EINVAL

An invalid argument was given to _locking.

Parameters

handle

File handle

mode

Locking action to perform

nbytes

Number of bytes to lock

Remarks

The _locking function locks or unlocks nbytes bytes of the file specified by handle. Locking bytes in a file prevents access to those bytes by other processes. All locking or unlocking begins at the current position of the file pointer and proceeds for the next nbytes bytes. It is possible to lock bytes past end of file.

mode must be one of the following manifest constants, which are defined in LOCKING.H:

_LK_LOCK

Locks the specified bytes. If the bytes cannot be locked, the program immediately tries again after 1 second. If, after 10 attempts, the bytes cannot be locked, the constant returns an error.

_LK_NBLCK

Locks the specified bytes. If the bytes cannot be locked, the constant returns an error.

_LK_NBRLCK

Same as _LK_NBLCK.

_LK_RLCK

Same as _LK_LOCK.

_LK_UNLCK

Unlocks the specified bytes, which must have been previously locked.

Multiple regions of a file that do not overlap can be locked. A region being unlocked must have been previously locked. _locking does not merge adjacent regions; if two locked regions are adjacent, each region must be unlocked separately. Regions should be locked only briefly and should be unlocked before closing a file or exiting the program.

Example

/* LOCKING.C: This program opens a file with sharing. It locks
* some bytes before reading them, then unlocks them. Note that the
* program works correctly only if the file exists.
*/

#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/locking.h>
#include <share.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

void main( void )
{
int fh, numread;
char buffer[40];

/* Quit if can't open file or system doesn't
* support sharing.
*/
fh = _sopen( "locking.c", _O_RDWR, _SH_DENYNO,
_S_IREAD | _S_IWRITE );
if( fh == -1 )
exit( 1 );

/* Lock some bytes and read them. Then unlock. */
if( _locking( fh, LK_NBLCK, 30L ) != -1 )
{
printf( "No one can change these bytes while I'm reading them\n" );
numread = _read( fh, buffer, 30 );
printf( "%d bytes read: %.30s\n", numread, buffer );
lseek( fh, 0L, SEEK_SET );
_locking( fh, LK_UNLCK, 30L );
printf( "Now I'm done. Do what you will with them\n" );
}
else
perror( "Locking failed\n" );

_close( fh );
}


Output

No one can change these bytes while I'm reading them
30 bytes read: /* LOCKING.C: This program ope
Now I'm done. Do what you will with them


File Handling Routines

See Also _creat, _open
wwww2 2012-09-24
  • 打赏
  • 举报
回复
要锁定文件的局部区域,可以用LockFile函数。这个函数我没怎么用过,可以自已查一下,看起来也比较简单的。
wwww2 2012-09-24
  • 打赏
  • 举报
回复
貌似这个不是异步读取的问题,只是一个多进程同时访问的问题。
你的代码中写入程序的在打开文件时指定的共享模式是FILE_SHARE_READ,这点是对的。
但是读取程序在打开文件时的共享模式设置为0,则表示尝试以独占模式打开文件,而该文件如果已被写入程序打开,则必定会返回失败。所以读取程序的共享模式需要设置为FILE_SHARE_WRITE才行。

另外,Windows的大部分函数失败后可以通过GetLastError()函数获取失败原因的错误代码,然后再用FormatMessage函数可获取错误信息的文字描述,这样遇到问题时就能知道错误的直接原因。
ReMeppo 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 的回复:]

windows好像比较垃圾,没有这么高级的能力。
[/Quote] 还是谢谢鸟。。。 慢慢找吧!!!
冷月清晖 2012-09-21
  • 打赏
  • 举报
回复
windows好像比较垃圾,没有这么高级的能力。
ReMeppo 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 的回复:]

引用 20 楼 的回复:

引用 19 楼 的回复:

_fsopen

非常感谢, 用CFILE 得换成C++, 现在项目都是用的C,没办法改!!!
用_fsopen可以同时打开 一个读一个写了。。。
不过 不知道有没有用于FILE* 的读写锁呢....


有啊,我之前的参考链接里。不光是读写,只要共享资源的情况都可以。
[/Quote]
跟需求有点不同哦.. 互斥量是进程间完全互斥了.. 信号灯只记数量 也不能区分进程操作是读还是写... 我是想 有木有像Unix一样 我单独锁 我将要写的那块区域, 其他区域不锁住! 其他进程仍可以读!
冷月清晖 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 的回复:]

引用 19 楼 的回复:

_fsopen

非常感谢, 用CFILE 得换成C++, 现在项目都是用的C,没办法改!!!
用_fsopen可以同时打开 一个读一个写了。。。
不过 不知道有没有用于FILE* 的读写锁呢....
[/Quote]

有啊,我之前的参考链接里。不光是读写,只要共享资源的情况都可以。
ReMeppo 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 的回复:]

_fsopen
[/Quote]
非常感谢, 用CFILE 得换成C++, 现在项目都是用的C,没办法改!!!
用_fsopen可以同时打开 一个读一个写了。。。
不过 不知道有没有用于FILE* 的读写锁呢....
赵4老师 2012-09-21
  • 打赏
  • 举报
回复
_fsopen
ReMeppo 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 的回复:]

不过好像用CFile没这个问题,
CreateFile不是线程间安全的。
[/Quote] 谢谢, 我试试!

暂时就想实现 多进程同时操作文件而已, 想不到实现 这个都这么纠结!
冷月清晖 2012-09-21
  • 打赏
  • 举报
回复
不过好像用CFile没这个问题,
CreateFile不是线程间安全的。
冷月清晖 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]

引用 13 楼 的回复:

听不懂.
为什么有读写锁 知道么?
[/Quote]

你光用share模式打开不够,系统无法知道你哪个进程取得了这个文件的控制权,必须用同步机制。
冷月清晖 2012-09-21
  • 打赏
  • 举报
回复
进程间同步

参考:关于线程和进程间的同步
ReMeppo 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]

听不懂.
[/Quote] 为什么有读写锁 知道么?
qq120848369 2012-09-21
  • 打赏
  • 举报
回复
听不懂.
ReMeppo 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

干啥????
[/Quote] 像给的代码里 一个进程 从文件末尾进行写操作, 另个进程 连CreateFile都失败了。。 更不用读内容了。。。
ReMeppo 2012-09-21
  • 打赏
  • 举报
回复
多进程文件操作同步啊, 不用一个进程的读操作一定要等到其他所有进程 closeHandle 后 才能读, 那样串行操作文件 速度太慢了!
qq120848369 2012-09-21
  • 打赏
  • 举报
回复
干啥????
加载更多回复(9)

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧