开2个线程, 写同一个文件, 怎么做?

xili 2005-09-01 04:57:14
开2个线程, 写同一个文件, 怎么做?
写的是不同的部分,无需担心互相覆盖.
有没有例子可以看看?
...全文
191 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
HaoyuTan 2005-09-02
  • 打赏
  • 举报
回复
// Create the I/O completion port.
hIOCompletionPort = CreateIoCompletionPort(hSourceFile,
NULL, // no existing I/O completion port
KEY, // key received in I/O completion packet
dwNumProcessors); // max worker threads

if (hIOCompletionPort == NULL)
{
fprintf(stderr,
"%s: Failed to create IO completion port (error %d)\n",
argv[0],
dwExitStatus = GetLastError());
goto EXIT;
}

// Initialize the file pointer for the overlapped structure
readPointer.LowPart = readPointer.HighPart = 0;

dwStartTime = GetTickCount();

// Start worker threads.
for (i=0; i<2*dwNumProcessors; i++)
{
hThread[i]=CreateThread(NULL,
0, // default stack size
(LPTHREAD_START_ROUTINE) readAndAnalyzeChunk,
(LPVOID) &fileSize,
0, // run immediately
&dwThreadId);
if (hThread[i] == NULL)
{
fprintf(stderr, "%s: Failed to create thread #%d (error %d)\n",
argv[0], i, dwExitStatus=GetLastError());
goto EXIT;
}
}
// Post the kickoff event.
PostQueuedCompletionStatus(hIOCompletionPort,
0,
KICKOFFKEY,
&kickoffOverlapped);

// Wait for a worker thread to terminate.
dwStatus = WaitForMultipleObjects(2*dwNumProcessors,
hThread,
FALSE,
INFINITE);
if (dwStatus == WAIT_FAILED)
{
fprintf(stderr, "%s: Wait failed (error %d)\n", argv[0],
dwExitStatus=GetLastError());
goto EXIT;
}
// Worker thread returned; send message to threads to exit.
for (i=0; i<2*dwNumProcessors-1; i++)
{
PostQueuedCompletionStatus(hIOCompletionPort,
0,
EXITKEY,
&dieOverlapped);
}
// Wait for threads to finish their work and terminate.
dwStatus = WaitForMultipleObjects(2*dwNumProcessors,
hThread,
TRUE,
INFINITE);

if (dwStatus == WAIT_FAILED)
{
fprintf(stderr, "%s: Wait failed (error %d)\n",
argv[0], dwExitStatus=GetLastError());
goto EXIT;
}
dwEndTime = GetTickCount();
printf( "\n\n%d bytes analyzed in %.3f seconds\n", fileSize.LowPart,
(float)(dwEndTime-dwStartTime)/1000.0);
printf( "%.2f MB/sec\n",
((LONGLONG)fileSize.QuadPart/(1024.0*1024.0))/(((float)(dwEndTime-dwStartTime))/1000.0));

EXIT:
(void) _getch();
if (bInit)
DeleteCriticalSection(&critSec);
if (hThread[i])
CloseHandle(hThread[i]);
if (hIOCompletionPort)
CloseHandle(hIOCompletionPort);
if (hSourceFile)
CloseHandle(hSourceFile);

exit(dwExitStatus);
}

//////////////////////////////////////////////////////////////////////
DWORD WINAPI readAndAnalyzeChunk(LPVOID lpParam)
{
BOOL bSuccess,
bMoreToRead;
DWORD dwNumBytes,
dwKey,
dwSuccess,
i,
repeatCnt,
dwThreadId;
LPOVERLAPPED completedOverlapped;
PCHUNK completedChunk;
CHUNK chunk;

printf("Thread (%d) started\n", dwThreadId=GetCurrentThreadId());

chunk.buffer=VirtualAlloc(NULL, BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE);

if (chunk.buffer==NULL)
{
fprintf(stderr, "VirtualAlloc failed (error %d)\n", GetLastError());
exit(1);
}

// Start asynchronous reads. Wait for read to complete, then do next read.
while(1){
bSuccess=GetQueuedCompletionStatus(hIOCompletionPort,
&dwNumBytes,
&dwKey,
&completedOverlapped,
INFINITE);
if (!bSuccess && (completedOverlapped==NULL))
{
fprintf(stderr, "GetQueuedCompletionStatus failed (error %d)\n", GetLastError());
exit(1);
}
if (dwKey==EXITKEY)
{
VirtualFree((LPVOID) chunk.buffer,
0,
MEM_RELEASE);
ExitThread(0);
}
if (!bSuccess)
{
fprintf(stderr, "GetQueuedCompletionStatus removed a bad I/O packet (error %d)\n", GetLastError());
// While you may want to fail here, this example proceeds.
}

if (dwKey != KICKOFFKEY)
{
// Analyze the data. The analysis for this example determines
// the number of pairs of consecutive bytes that are equal.
printf("Analyzing %d byte chunk\n", dwNumBytes);
completedChunk = (PCHUNK)completedOverlapped;
repeatCnt = 0;
for (i = 1; i < dwNumBytes; i++)
if ((((PBYTE)completedChunk->buffer)[i - 1] ^ ((PBYTE)completedChunk->buffer)[i]) == 0)
repeatCnt++;
printf("Repeat count was %d (thread #%d)\n", repeatCnt, dwThreadId);

// If the number of bytes returned is less than BUFFER_SIZE,
// that was the last read. Exit the thread.
if (dwNumBytes < BUFFER_SIZE)
ExitThread(0);
}
// Adjust OVERLAPPED structure for next read.
EnterCriticalSection(&critSec);

if (readPointer.QuadPart < ((ULARGE_INTEGER *)lpParam)->QuadPart)
{
bMoreToRead = TRUE;
chunk.overlapped.Offset = readPointer.LowPart;
chunk.overlapped.OffsetHigh = readPointer.HighPart;
chunk.overlapped.hEvent = NULL; // not needed

// Set the file pointer for the next reader
readPointer.QuadPart += BUFFER_SIZE;
}
else bMoreToRead = FALSE;

LeaveCriticalSection(&critSec);

// Issue the next read.

if (bMoreToRead)
{
dwSuccess = ReadFile(hSourceFile,
chunk.buffer,
BUFFER_SIZE,
&dwNumBytes,
&chunk.overlapped);
if (!dwSuccess && (GetLastError() == ERROR_HANDLE_EOF))
printf( "End of file\n" );
if (!dwSuccess && (GetLastError() != ERROR_IO_PENDING))
fprintf (stderr, "ReadFile at %lx failed (error %d)\n",
chunk.overlapped.Offset,
GetLastError());
}
} // end while
}
HaoyuTan 2005-09-02
  • 打赏
  • 举报
回复
Example Code

[C++]
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>

// Assume for this sample that we have a maximum of 16 processors.
#define MAX_THREADS 32
#define BUFFER_SIZE (64*1024)
DWORD dwNumProcessors;

// Handle for the source file to be analyzed
HANDLE hSourceFile=NULL;

// Handle to the I/O completion port
HANDLE hIOCompletionPort=NULL;

// Read position
ULARGE_INTEGER readPointer;

// Critical section
CRITICAL_SECTION critSec;

// ThreadProc function
DWORD WINAPI readAndAnalyzeChunk(LPVOID lpParam);

// Keys that control the behavior of the worker threads.
#define KICKOFFKEY 99 // Start reading and analyze the file
#define KEY 1 // Read the next chunk and analyze it
#define EXITKEY 86 // Exit (the file has been read and analyzed)

// Structure for tracking outstanding I/O
typedef struct _CHUNK {
OVERLAPPED overlapped;
LPVOID buffer;
} CHUNK, *PCHUNK;

//////////////////////////////////////////////////////////////////////
int main(
int argc,
char *argv[],
char *envp)
{
HANDLE hThread[MAX_THREADS];
DWORD dwThreadId,
dwStatus,
dwStartTime,
dwEndTime,
dwExitStatus = ERROR_SUCCESS;
ULARGE_INTEGER fileSize,
readPointer;
SYSTEM_INFO systemInfo;
UINT i;
BOOL bInit=FALSE;
OVERLAPPED kickoffOverlapped,
dieOverlapped;

// Make sure a source file is specified on the command line.

if (argc != 2)
{
fprintf(stderr, "Usage: %s <source file>\n", argv[0]);
dwExitStatus=1;
goto EXIT;
}

// Get the number of processors on the system.

GetSystemInfo(&systemInfo);
dwNumProcessors = systemInfo.dwNumberOfProcessors;

// Open the source file.

hSourceFile = CreateFile(argv[1],
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED,
NULL);
if (hSourceFile == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "%s: Failed to open %s, error %d\n",
argv[0],
argv[1],
dwExitStatus = GetLastError());
goto EXIT;
}
fileSize.LowPart = GetFileSize(hSourceFile, &fileSize.HighPart);

if ((fileSize.LowPart==0xffffffff) && (GetLastError()!= NO_ERROR))
{
fprintf(stderr, "%s: GetFileSize failed, error %d\n",
argv[0],
dwExitStatus = GetLastError());
goto EXIT;
}

// Use a criticial section to serialize access by multiple threads.
InitializeCriticalSection(&critSec);
bInit=TRUE;

HaoyuTan 2005-09-02
  • 打赏
  • 举报
回复
用异步IO,任意多线程也没有问题,具体的方式是使用IO完成端口,这里给出一个MSDN上的例子:

Example Details

The sample code demonstrates a multi-threaded application designed to read and analyze a large file. Asynchronous I/O is used to read a chunk of the file at a time by one of a pool of worker threads. The completed I/O is posted at an I/O completion port. A worker thread picks up the completed I/O, analyzes it, reports the results, and starts another asynchronous read operation. The process continues until the whole file has been read.

The number of threads is based on the number of processors in the host. Specifically, it is twice that number. See I/O Completion Ports for more details.

The contrived "analysis" is a count of the number of identical consecutive byte pairs in each chunk.

The file to be analyzed is specified on the command line. The sample is most meaningful if the specified file that is 1MB or larger in size.

The code consists of a single thread running the main function and several identical worker threads running the function named readAndAnalyzeChunk. These functions are described following.

main function

Determines the number of processors, which is related to the concurrency value for the I/O completion port.
Opens the source file to be analyzed for unbuffered asynchronous I/O.
Determines the size of the file.
Initializes a read pointer that will be accessed by worker threads within a critical section.
Creates a single I/O completion port at which completed reads post.
Creates a pool of worker threads (twice the number of processors on the system) and starts each one running readChunkAndAnalyze.
Posts a single "kickoff" I/O completion at the I/O completion port, which causes the worker threads to begin.
Waits for any one of the worker threads to exit, signifying that it has analyzed the data that was read from the last chunk of the file.
Posts a set of "exit" I/O completions at the I/O completion port. This this indicates that the threads should exit after completing any remaining analysis.
Waits for all threads to terminate.
Displays some statistics and exits.
readAndAnalyzeChunk function

Waits on a completed I/O at the I/O completion port upon creation.
One thread begins reading the file when the "kickoff" key is posted by the main program.
Analyzes the data block returned by entering a critical section, retrieving the read pointer, updating the read pointer for the next thread, leave the critical section.
Exits when the "exit" key is posted.

Practise_Think 2005-09-01
  • 打赏
  • 举报
回复
InterlockedExchangeAdd
hundlom 2005-09-01
  • 打赏
  • 举报
回复
互斥
ss3295 2005-09-01
  • 打赏
  • 举报
回复
FTP好象就是这样的
Jarrylogin 2005-09-01
  • 打赏
  • 举报
回复
CCriticalSection
dch4890164 2005-09-01
  • 打赏
  • 举报
回复
使用临界区就可以吧
xili 2005-09-01
  • 打赏
  • 举报
回复
俺的意思是, 两个线程各有自己的 FILE*fp
或 FileHandle
xili 2005-09-01
  • 打赏
  • 举报
回复
同步这方面基本没问题

fopen() 或 CreateFile()要怎么设置参数?
xili 2005-09-01
  • 打赏
  • 举报
回复
这里人气旺,俺喜欢,谢谢各位.
去看看先.

继续欢迎指教.
DentistryDoctor 2005-09-01
  • 打赏
  • 举报
回复
使用临界区进行同步。
快乐鹦鹉 2005-09-01
  • 打赏
  • 举报
回复
用互斥能接受么?
老夏Max 2005-09-01
  • 打赏
  • 举报
回复
http://www.vckbase.com/document/viewdoc/?id=804
老夏Max 2005-09-01
  • 打赏
  • 举报
回复
使用同步:
http://www.vckbase.com/document/viewdoc/?id=758
在Windows 10或Windows 11操作系统中,用户经常会遇到共享打印机时出现的一系列错误代码,这些错误代码可能会阻碍打印机共享功能的正常使用。常见的错误代码包括0x00000057、0x00000709和0x0000011b,这些代码通常指出了不同的问题,比如权限不足、服务未运行或配置错误等。除此之外,还有一些故障提示如“连接失败”或“内存不足”,这些都可能影响到打印机共享的稳定性。 要解决这些故障,首先要确保打印机已经正确地连接到网络,并且在需要共享的电脑上进行了设置。确保打印机驱动程序是最新的,并且在共享设置中没有错误配置。对于权限问题,需要检查网络上的用户账户是否具有足够的权限来访问共享打印机。同时,也要确保打印机服务正在运行,特别是“Print Spooler”服务,因为这是打印机共享服务的核心组件。 在某些情况下,问题可能与操作系统的更新有关,如升级到最新版的Windows 10或Windows 11后可能出现的兼容性问题。这时,可能需要查看微软的官方支持文档来获取特定的解决方案或更新。 对于错误代码0x00000057,这通常是由于没有足够的权限来访问网络打印机或其共享资源,解决方法是确保网络打印机的权限设置正确,包括在组策略中设置相应的访问权限。而0x00000709错误可能是由于打印机驱动问题或打印机端口配置错误,可以尝试重新安装或更新打印机驱动来解决。至于0x0000011b错误,这往往是因为打印机队列服务的问题,检查并重启“Print Spooler”服务通常是解决这类问题的常见手段。 至于“连接失败”或“内存不足”这类故障,通常与客户端和打印机之间的网络连接以及打印机本地资源的使用情况有关。检查网络连接,确保打印机所在的网络段没有故障或中断。同时,如果打印机的打印队列长时间得不到处理,可能会导致内存不足的情况,这时可能需要清理打印队列或增加打印机的内存配置。 为了帮助用户更快速地解决这些问题,市面上出现了各种打印机共享错误修复工具。这些工具往往通过预设的修复程序来自动检测和修正打印机共享中常见的问题。它们可以快速检查打印机驱动、网络连接以及共享设置,并且能够提供一键修复功能,大幅减少了用户自行排查和解决问题的难度。 然而,在使用这些修复工具之前,用户应确保这些工具的来源是安全可靠的,避免因使用不当的修复工具而引发其他系统安全或隐私问题。用户可以到官方平台或者信誉良好的软件提供商处下载这些工具。通过细心检查打印机的共享设置,及时更新驱动程序和服务,以及合理使用修复工具,大多数共享打印机的问题都可以得到有效的解决。

15,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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