如果在多个子thread中fopen同一文件,fseek不同位置, fwrite(也加过fflush), fclose, 文件大多数都是空白,只有很小部分有内容(进行操作时均使用了临界区)但如果在主thread中多次fopen, 把每个fp传递给多个子thread,然后再fseek到不同位置,再fwrite,最后在主thread中fclose,得到的结果正常。(进行操作时均使用了临界区)why? 有没有高手能解释明白?感激不尽!!!!
注:子thread是用CreateThread开始的,没用_beginthreadex等。
主thread是进程中的主thread.
注:子thread是用CreateThread开始的,没用_beginthreadex等。
主thread是进程中的主thread.
太长了,实在整理不出简短的代码来。TO jink
谢谢提醒,回去看看~~~~~~
我的所由代码都在一个进程中, 不存在"句柄是进程级"的问题.
还有,我三年前就在CSDN里了, VB版中我是二星专家(是两年前获得的)
平时事很多,只能去VB版回答一些比较简单的问题, VC版来的不多, 但也有几千专家分.
前段时间事更多了, 以至无暇光顾CSDN, 最近空闲下来才回来看看.如果你怀疑我是倒分, 你可以搜索一下我所有的问题 , 看看我的分到底给了谁.
顺便告诉你怎么看, 在搜索里 主题 中输入一个空格, 作者中填入chice_wxg,
你搜一下就知道了.当然,如果你能解决这个问题, 分自然是你的. 我也可以另开贴子给分,我还有5000多
可用分,你想要多少我都给你----前提是你能解决这个问题.
而实际填充buf的时候填充的是可见字符。代码随便改,只要完成这个任务就可以了,不要用CreateFile和_beginthread等Win32特有的函数(临界区和线程控制在其他OS下照样可以实现)。
另
TO GodInNight(夜游神)
你对自己很自信的话来试试。很多问题远比你想象的复杂。// ThreadTest.cpp : Defines the entry point for the console application.
//#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>typedef struct _PARAM
{
FILE *fp;
INT idx;
}PARAM;CRITICAL_SECTION cs;DWORD WINAPI ThreadProc(LPVOID lpParam)
{
char buf[100];
int i;
PARAM *param = (PARAM *)lpParam; for(i=30;i<130;i++)
buf[i - 30] = i; param->fp = fopen("C:\\test.bin", "wb"); if(param->fp)
{
fseek(param->fp, param->idx * 10000, SEEK_SET);
for(i=0;i<100;i++)
{
EnterCriticalSection(&cs);
fwrite(buf, 100, 1, param->fp);
fflush(param->fp);
LeaveCriticalSection(&cs);
} printf("Thread %d finished.\r\n", param->idx);
fclose(param->fp);
}
else
{
printf("Thread %d FILE ERROR!\r\n", param->idx);
} delete param; return 0;
}
int main(int argc, char* argv[])
{
PARAM *param;
DeleteFile("C:\\test.bin"); InitializeCriticalSection(&cs); for(int i=0;i<10;i++)
{
param = new PARAM;
param->fp = NULL;
param->idx = i;
CreateThread(NULL, 0, ThreadProc, param, 0, NULL);
}
puts("Wait for threads to finish");
getch();
DeleteCriticalSection(&cs);
return 0;
}
理论上test.bin应该全部有内容的。实际却不是。麻烦各位高手帮忙Debug :)解决后另送200分。
说明,你只有一个线程在写这个文件。当然,只有一个线程写的结果。
以下代码几乎没变,但可以正确建立一个文件:DWORD WINAPI ThreadProc(LPVOID lpParam)
{
char buf[100];
int i;
PARAM *param = (PARAM *)lpParam; for(i=30;i<130;i++)
buf[i - 30] = i; param->fp = fopen("C:\\test.bin", "wb"); Sleep(100); //Here!!!//难道说等待所有thread把文件都"wb"打开了然后再一起写就正常了?
//不知道MSCLib和Windows是如何处理这种情况的? if(param->fp)
{
fseek(param->fp, param->idx * 10000, SEEK_SET); for(i=0;i<100;i++)
{
EnterCriticalSection(&cs);
fwrite(buf, 100, 1, param->fp);
LeaveCriticalSection(&cs);
} printf("Thread %d finished.\r\n", param->idx);
fclose(param->fp);
}
else
{
printf("Thread %d FILE ERROR!\r\n", param->idx);
} delete param; return 0;
}
高手指点,谢谢~~~~~~~~~~~
安全吗?TO GodInNight(夜游神)
其实线程等部分的代码我早就做好了。
而且我已经用另一种方法,也解决文件问题,我的程序已经可以同时
在Linux/Win32上正常工作了。只是遇到了这个问题很奇怪,所以我才会来问。我对多线程编程了解也不是很深,希望高手帮忙指点指点~~~~~
前面的线程写入的数据都被清空了, 而之后再写入的数据就保留了下来,所以只有一小部分数据,而且每次都不一样, 改用_open, _lseek, _write就可以了.
下面是MSDN的原话:
"w"
Opens an empty file for writing. If the given file exists, its contents are destroyed.
param->fp = _fsopen("C:\\test.bin", "ab", _SH_DENYNO);
int main(int argc, char* argv[])
{
PARAM *param;
DeleteFile("C:\\test.bin"); InitializeCriticalSection(&cs);
FILE *fp = fopen("C:\\test.bin", "wb"); for(int i=0;i<10;i++)
{
param = new PARAM;
param->fp = fp;
param->idx = i;
CreateThread(NULL, 0, ThreadProc, param, 0, NULL);
}
puts("Wait for threads to finish");
getch();
DeleteCriticalSection(&cs);
fclose(fp);
return 0;
}
{
char buf[100];
int i;
PARAM *param = (PARAM *)lpParam; for(i=30;i<130;i++)
buf[i - 30] = i;
if(param->fp)
{
for(i=0;i<100;i++)
{
EnterCriticalSection(&cs);
fseek(param->fp, param->idx * 10000 + i*100, SEEK_SET);
fwrite(buf, 100, 1, param->fp);
fflush(param->fp);
LeaveCriticalSection(&cs);
} printf("Thread %d finished.\r\n", param->idx);
}
else
{
printf("Thread %d FILE ERROR!\r\n", param->idx);
} delete param; return 0;
}
觉得上面的还是有问题(打开的文件在多线程中会存在争用,特别是文件指针)
用内存仰射文件应该要来的爽一些
还有就是_fsopen或内存Mapping无法在Linux下实现
其实我现在是使用 fopen( , "rb+") 来操作的。只是很奇怪fopen("wb")的时候系统的行为。其实到现在我也不是很明白。本来想看看crt库是如何实现的,结果看了就头疼~~~~~~~~谢谢各位帮忙,此帖再放一天,然后结帐~~~~~~~~~~~~
---------------------
不用看了……临界区保护的不足