使用Win32 API在C ++中使用多线程创建多个文件

时间:2011-08-02 05:17:12

标签: c++ c winapi visual-c++

我正在尝试在笔式驱动器中创建文件。如果没有笔式驱动器,则应暂停线程。插入时应该恢复。这是我尝试的代码,但它无法正常工作。任何人都可以帮助我吗?

 #include "stdafx.h"
    #include <Windows.h>
    #include <Strsafe.h>
    #include <WinBase.h>


        LPCTSTR Disk=L"E:\";

        LPTSTR drive_Name=L"E:\\demo";

        CRITICAL_SECTION section;


         #define BUFFER_SIZE 1024
         #define count 10

        HANDLE Write_Handle[10],Open_Handle[10],read_Handle[10] ;

        DWORD WINAPI check_Thread(LPVOID lpParameter)

        {

        int *nThreadNo = (int*)lpParameter;

        while(1)

        {

                if(GetDiskFreeSpaceExW(Disk,NULL,NULL,NULL))

                {

                    ResumeThread(Write_Handle[*nThreadNo]);
                    ResumeThread(read_Handle[*nThreadNo]);
                }
                else
                {
                    SuspendThread(Write_Handle[*nThreadNo]);
                    SuspendThread(read_Handle[*nThreadNo]);
                }
            }

        }


        DWORD  WINAPI Write_Thread(LPVOID lpParameter)
        {
            DWORD g_tid = GetCurrentThreadId();
            _tprintf(_T(" write thread id %d\n"),g_tid);
            LPCWSTR  filename=(LPCWSTR)lpParameter;
            HANDLE ofile;
            EnterCriticalSection(&section);
            ofile=CreateFileW(filename,GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,NULL, NULL);
            int d;
                d=GetLastError();
                if(ERROR_SUCCESS!=GetLastError())
                {
                    _tprintf(_T("error values in open thread %d \n"),GetLastError());
                    _tprintf(_T("filename %s \n"),filename);
                }

            const int filesizeinKB = 1024;
            BOOL bError;
            DWORD dwBytesWritten=0;
             WCHAR ReadBuffer[BUFFER_SIZE] = {0};
            int i;


            for(i = 0; i <= BUFFER_SIZE; i++)
            {
                ReadBuffer[i] = (char)(i%26 + 'a');
            }
            for (i = 0; i <= filesizeinKB; i++)
            {
                SetLastError(0);
                bError= WriteFile(ofile, ReadBuffer-1, BUFFER_SIZE,&dwBytesWritten, NULL);
                bError=GetLastError();

                if (ERROR_SUCCESS!=GetLastError())
                {   _tprintf(_T("error value in write %d\n"),GetLastError());
                    _tprintf(_T(" Write Error...\n"));
                        return 1;
                }

            }
            SetLastError(0);
            CloseHandle(ofile);
            _tprintf(_T("write close error values %d\n"),GetLastError());
            LeaveCriticalSection(&section);
            return 1;
        }


        DWORD WINAPI Read_Thread(LPVOID lpParameter)
        {
            HANDLE ofile;
            DWORD g_tid = GetCurrentThreadId();
            _tprintf(_T(" write thread id %d\n"),g_tid);
            LPCWSTR  filename=(LPCWSTR)lpParameter;
            EnterCriticalSection(&section);
            ofile=CreateFileW(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_ALWAYS,NULL, NULL);
            int d;
                d=GetLastError();
                if(ERROR_SUCCESS!=GetLastError())
                {
                    _tprintf(_T("error values in open thread %d \n"),GetLastError());
                    _tprintf(_T("filename %s \n"),filename);
                }

            DWORD dwBytesRead=0;
             WCHAR ReadBuffer[BUFFER_SIZE] = {0};
            _tprintf(_T(" read thread \n"));
            SetLastError(0);
            int err;

            ReadFile(ofile, ReadBuffer, (BUFFER_SIZE-1), &dwBytesRead, NULL);

                err=GetLastError();
                _tprintf(_T("read error values %d \n"),GetLastError());
                if(ERROR_SUCCESS!=GetLastError())
                {
                    _tprintf(L"reading failed \n");
                    return 0;
                }
                SetLastError(0);
                CloseHandle(ofile);
                err=GetLastError();
                _tprintf(_T("close error values %d\n"),GetLastError());
                LeaveCriticalSection(&section);
                return 1;
        }


        int _tmain(int argc, _TCHAR* argv[])
        {

            unsigned int myCounter = 0;
            DWORD WritethreadID,OpenThreadID,ReadthreadID;
            HANDLE check_Handle;
             DWORD exThread;
            TCHAR filename[100];
            HANDLE hfile;
            INT bsize=100;
            int i=0;

            InitializeCriticalSection (&section);
            CreateDirectory(drive_Name,NULL);

            for(i=0;i<5;i++)
            {
                SetLastError(0);
                StringCchPrintf(filename,bsize, TEXT("%s\\file_%d.txt"),drive_Name,i );
                hfile=CreateFileW(filename,GENERIC_WRITE|GENERIC_READ,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

                if (hfile == INVALID_HANDLE_VALUE) 
                { 
                    _tprintf(_T("invalid handle \n" ));

                }
                _tprintf(_T("file created %s\n"),filename);
                CloseHandle(hfile);

                Write_Handle[i] =CreateThread(0, 0, Write_Thread, filename, CREATE_SUSPENDED, &WritethreadID);
                SetThreadPriority(Write_Handle[i],2);
                _tprintf(_T("write thread id is %d\n"),WritethreadID);
                read_Handle[i]=CreateThread(0, 0, Read_Thread, filename, CREATE_SUSPENDED, &ReadthreadID);
                SetThreadPriority(read_Handle[i],1);
                _tprintf(_T("read thread id is %d\n "),ReadthreadID);
                check_Handle =CreateThread(0, 0, check_Thread,(void*)&i ,0,&OpenThreadID);
            }   
            for (i=0; i<count; ++i)
            {
                WaitForSingleObject(Write_Handle[i],INFINITE); 
                if ( !GetExitCodeThread(Write_Handle, &exThread) ) 
                {  
                    _tprintf(_T("close thread %08X\n"),GetLastError()); 

                }
                SetLastError(0);
                CloseHandle(Write_Handle[i]);
                _tprintf(_T("close thread %08X\n"),GetLastError()); 
                WaitForSingleObject(read_Handle[i],INFINITE); 
                if ( !GetExitCodeThread(read_Handle, &exThread) ) 
                {  
                    _tprintf(_T("GetExitCodeThread %08X\n"),GetLastError()); 
                } 
                SetLastError(0);
                CloseHandle(read_Handle[i]);
                _tprintf(_T("GetExitCodeThread %08X\n"),GetLastError()); 

                CloseHandle(check_Thread);

            }

            DeleteCriticalSection(&section);
            return 1;

        }

2 个答案:

答案 0 :(得分:3)

如果在删除该驱动器时已打开USB驱动器的文件句柄,则这些文件句柄将变为无效。重新插入USB驱动器将重新构建这些句柄,以便在恢复线程后继续。

您需要:

  • 检测设备何时被移除,并关闭那些现已损坏的句柄
  • 插入设备后,再次打开文件并继续执行您正在执行的操作

答案 1 :(得分:0)

您的错误处理程序在不调用LeaveCriticalSection的情况下返回,导致CS被锁定并无限期地阻塞其他线程。来自EnterCriticalSection docs:

  • 如果线程在拥有关键部分的所有权时终止, 临界区的状态未定义。

这些情况也会使文件句柄处于打开状态。