Task 23. Asynchronous reading from a file.

Task type: development.

Difficulty level: advanced.

When reading data from a file asynchronously , after issuing a read command, the thread does not block until the operation is completed, but continues its work. On Windows, asynchronous I/O is called overlapped I/O. Asynchronous I/O in Windows is performed by the “normal” ReadFile and WriteFile functions , but the file must be opened in FILE_FLAG_OVERLAPPED mode.

You can find out about the completion of an I/O operation either by the fact that the file descriptor goes into the signaled state (this method is not suitable if several I/O threads are working with the file at the same time), or by using a special event set by the OS when the operation is completed into the signaled state. The handle to this event must be in an OVERLAPPED structure whose address is passed to the asynchronous I/O functions.

When several asynchronous I/O operations are running at the same time, for each of them you need to define its own structure, in which you specify the descriptor of a separate event associated with this I/O operation.

Recommended sources:

· Stallings V. Operating systems, 4th ed.: – M.: Ed. house “Williams”, 2002.

· Electronic reference book “Win32 Programmer’s Reference” from the “MS SDK Help Files”.

Project task:

· To get acquainted with the mechanism of asynchronous input-output of OS Windows.

· Learn the purpose and use of API functions for working with events.

· Review relevant API functions.

· Develop and implement a program according to the condition of the problem.

· Develop a set of tests to demonstrate the functionality and correctness of the program.

· Prepare a report on the course project.

Task:

Implement programs for asynchronous reading of data from a file using a handle and multiple asynchronous reading using events.

Design, code and debug programs.

Implementation language – arbitrary, OS – Windows.

APPENDIX B

( Block diagram of the program operation algorithm )


APPENDIX B

( Listing of program implementation of asynchronous reading from a file)

#include

#include

#include

using namespace std;

const int N=1019000;//Number of bytes to read

HANDLE hFile;

HANDLE hEvent1,hEvent2;

int threadsWork=0;

char* rus(char* message)

{

char* tmp=new char[strlen(message)+1];

CharToOem(message,tmp);

return tmp;

}

void Monitor1(void *)

{

DWORD dwWaitResult=1;

while(dwWaitResult!=WAIT_OBJECT_0)//If reading has not finished

{

dwWaitResult = WaitForSingleObject(hEvent1,1); //Waiting for the end of reading event

cout<

}

threadsWork–;

cout<

_endthread();//end thread

}

void Monitor2(void *)

{

DWORD dwWaitResult=1;

while(dwWaitResult!=WAIT_OBJECT_0)//If reading has not finished

{

dwWaitResult = WaitForSingleObject(hEvent2,1);//We are waiting for the read end event

cout<

}

threadsWork–;

cout<

_endthread();//end thread

}

void thread1(void*)

{

char inBuffer[N+1]=””;

DWORD nBytesToRead=N,nBytesRead,dwError;

hEvent1=CreateEvent(NULL,true,false,”event1″);//create a read end event

if(hEvent1==NULL)

{

charerror[30];

sprintf(error,”Such event already exists (error %d)”,GetLastError());

cout<

system(“pause”);

exit(-1);

}

OVERLAPPED gOverLapped;

// prepare the fields of the structure of the asynchronous operation

gOverLapped.Offset = 0;

gOverLapped.OffsetHigh = 0;

gOverLapped.hEvent = hEvent1;

bool bResult;

//do{

// trying to perform an asynchronous read operation

bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead,&gOverLapped) ;

// if there is a problem or an asynchronous operation

// still waiting to be processed…

if (!bResult&&GetLastError()==ERROR_HANDLE_EOF)

{

// we’ve reached the end of the file

// during the call to ReadFile

cout<

//break;

} // end of if procedure

//cout<<" 1="<

//gOverLapped.Offset+=nBytesRead;}while(bResult);

cout<

CloseHandle(hEvent1);//Close event handle

_endthread();//end thread

}

void thread2(void*)

{

char inBuffer[N+1]=””;

DWORD nBytesToRead=N,nBytesRead,dwError;

hEvent2=CreateEvent(NULL,true,false,”event2″);//create a read end event

if(hEvent2==NULL)

{

charerror[30];

sprintf(error,”Such event already exists (error %d)”,GetLastError());

cout<

system(“pause”);

exit(-1);

}

OVERLAPPED gOverLapped;

// prepare the fields of the structure of the asynchronous operation

gOverLapped.Offset = 0;

gOverLapped.OffsetHigh = 0;

gOverLapped.hEvent = hEvent2;

bool bResult;

//do{

// trying to perform an asynchronous read operation

bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead,&gOverLapped) ;

// if we reached the end of the file

if (!bResult&&GetLastError()==ERROR_HANDLE_EOF)

{

// we’ve reached the end of the file

// during the call to ReadFile

cout<

//break;

} // end of if procedure

//cout<<" 2="<

//gOverLapped.Offset+=nBytesRead;}while(bResult);

cout<

CloseHandle(hEvent2);//Close event handle

_endthread();//end thread

}

void main()

{

if (_beginthread(Monitor1,1024,NULL)==-1)//Starting the event monitor of the first thread

cout <

if (_beginthread(Monitor2,1024,NULL)==-1)//Launch the event monitor of the second thread

cout << rus("nError starting monitor thread 2n")<< endl;

char fileName[]=”D:\file1.txt”;

hFile=CreateFile(fileName, // File to open

GENERIC_READ, // Open for reading

FILE_SHARE_READ, // Shared Read

NULL, // Default security

OPEN_EXISTING, // Existing file only

FILE_ATTRIBUTE_NORMAL, // Regular file

NULL); // No template attributes

if (hFile == INVALID_HANDLE_VALUE) //If an error occurred

{

charerror[30];

sprintf(error,”Failed to open file (error %d)”,GetLastError());

cout<

system(“pause”);

exit(-1);

}

if (_beginthread(thread2,1024,NULL)==-1)//Starting the second reading thread

cout <

else threadsWork++;

if (_beginthread(thread1,1024,NULL)==-1)//Starting the first reading thread

cout <

else threadsWork++;

while(threadsWork);//Wait for the end of the reading threads

CloseHandle(hFile);//Close the file

cout<

system(“pause”);

}

Be First to Comment

Leave a Reply

Your email address will not be published.