MultiRead: Reads Database Table Using Multiple Threads

Click to open or copy the MultiRead project files.

This sample demonstrates how to use the OLE DB consumer template classes to read through a table in a database using multiple threads. The sample contains the CMultiDlg class, which is used to show a dialog. With this dialog, the user enters the number of threads to use to read through the table. When the user clicks the Run button, ReadRecords in dbtest.h is called to open the database, the session, and the table, and to create the necessary number of threads. As it opens the table, the function sets the DBPROP_CANHOLDROWS property to true so that the provider allows the user to retrieve new rows without releasing the previously-retrieved rows. This capability is required, because multiple threads retrieves new rows as other threads are still processing their current threads.

The sample also shows how to extend the standard CRowset class by creating a new CMyRowset class, which derives from CRowset, and adds the MoveAndProcess member function. The start routine of each thread is the ReadTable function and the table class is passed to this function. The function calls the routine MoveAndProcess to read through each record. Note that the accessor class CProduct is defined so that the data will not be retrieved automatically on the MoveNext call. Consequently, we don’t have to worry about buffer conflicts with the other threads, and we don’t need to protect MoveNext with a critical section. The MoveAndProcess function calls MoveNext, and then calls GetDataHere to place the data directly into a local variable of that function. ProcessRecord is called for each record retrieved and the function simply traces out the values of the record by default.

Each thread counts the number of records it reads, and those are traced out at the end, along with a total and time taken, which is displayed on the dialog.

The sample demonstrates the following classes:

CAccessor, CDataSource, CDBPropSet, CRowset, CSession, CTable

the following macros:

BEGIN_ACCESSOR_MAP, BEGIN_ACCESSOR, COLUMN_ENTRY, END_ACCESSOR, END_ACCESSOR_MAP, DEFINE_COMMAND

and the following functions:

CreateThread, GetCurrentThreadId, GetExitCodeThread, WaitForMultipleObjects