Guest User

Untitled

a guest
May 23rd, 2018
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.45 KB | None | 0 0
  1.  
  2. #include <windows.h>
  3. #include <tchar.h>
  4. #include <strsafe.h>
  5.  
  6. #define MAX_THREADS 3
  7. #define BUF_SIZE 255
  8.  
  9. DWORD WINAPI MyThreadFunction( LPVOID lpParam );
  10. void ErrorHandler(LPTSTR lpszFunction);
  11.  
  12. // Sample custom data structure for threads to use.
  13. // This is passed by void pointer so it can be any data type
  14. // that can be passed using a single void pointer (LPVOID).
  15. typedef struct MyData {
  16.     int val1;
  17.     int val2;
  18. } MYDATA, *PMYDATA;
  19.  
  20.  
  21. int _tmain()
  22. {
  23.     PMYDATA pDataArray[MAX_THREADS];
  24.     DWORD   dwThreadIdArray[MAX_THREADS];
  25.     HANDLE  hThreadArray[MAX_THREADS];
  26.  
  27.     // Create MAX_THREADS worker threads.
  28.  
  29.     for( int i=0; i<MAX_THREADS; i++ )
  30.     {
  31.         // Allocate memory for thread data.
  32.  
  33.         pDataArray[i] = (PMYDATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
  34.                 sizeof(MYDATA));
  35.  
  36.         if( pDataArray[i] == NULL )
  37.         {
  38.            // If the array allocation fails, the system is out of memory
  39.            // so there is no point in trying to print an error message.
  40.            // Just terminate execution.
  41.             ExitProcess(2);
  42.         }
  43.  
  44.         // Generate unique data for each thread to work with.
  45.  
  46.         pDataArray[i]->val1 = i;
  47.         pDataArray[i]->val2 = i+100;
  48.  
  49.         // Create the thread to begin execution on its own.
  50.  
  51.         hThreadArray[i] = CreateThread(
  52.             NULL,                   // default security attributes
  53.             0,                      // use default stack size  
  54.             MyThreadFunction,       // thread function name
  55.             pDataArray[i],          // argument to thread function
  56.             0,                      // use default creation flags
  57.             &dwThreadIdArray[i]);   // returns the thread identifier
  58.  
  59.  
  60.         // Check the return value for success.
  61.         // If CreateThread fails, terminate execution.
  62.         // This will automatically clean up threads and memory.
  63.  
  64.         if (hThreadArray[i] == NULL)
  65.         {
  66.            ErrorHandler(TEXT("CreateThread"));
  67.            ExitProcess(3);
  68.         }
  69.     } // End of main thread creation loop.
  70.  
  71.     // Wait until all threads have terminated.
  72.  
  73.     WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
  74.  
  75.     // Close all thread handles and free memory allocations.
  76.  
  77.     for(int i=0; i<MAX_THREADS; i++)
  78.     {
  79.         CloseHandle(hThreadArray[i]);
  80.         if(pDataArray[i] != NULL)
  81.         {
  82.             HeapFree(GetProcessHeap(), 0, pDataArray[i]);
  83.             pDataArray[i] = NULL;    // Ensure address is not reused.
  84.         }
  85.     }
  86.  
  87.     return 0;
  88. }
  89.  
  90.  
  91. DWORD WINAPI MyThreadFunction( LPVOID lpParam )
  92. {
  93.     HANDLE hStdout;
  94.     PMYDATA pDataArray;
  95.  
  96.     TCHAR msgBuf[BUF_SIZE];
  97.     size_t cchStringSize;
  98.     DWORD dwChars;
  99.  
  100.     // Make sure there is a console to receive output results.
  101.  
  102.     hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
  103.     if( hStdout == INVALID_HANDLE_VALUE )
  104.         return 1;
  105.  
  106.     // Cast the parameter to the correct data type.
  107.     // The pointer is known to be valid because
  108.     // it was checked for NULL before the thread was created.
  109.  
  110.     pDataArray = (PMYDATA)lpParam;
  111.  
  112.     // Print the parameter values using thread-safe functions.
  113.  
  114.     StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Parameters = %d, %d\n"),
  115.         pDataArray->val1, pDataArray->val2);
  116.     StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);
  117.     WriteConsole(hStdout, msgBuf, (DWORD)cchStringSize, &dwChars, NULL);
  118.  
  119.     return 0;
  120. }
  121.  
  122.  
  123.  
  124. void ErrorHandler(LPTSTR lpszFunction)
  125. {
  126.     // Retrieve the system error message for the last-error code.
  127.  
  128.     LPVOID lpMsgBuf;
  129.     LPVOID lpDisplayBuf;
  130.     DWORD dw = GetLastError();
  131.  
  132.     FormatMessage(
  133.         FORMAT_MESSAGE_ALLOCATE_BUFFER |
  134.         FORMAT_MESSAGE_FROM_SYSTEM |
  135.         FORMAT_MESSAGE_IGNORE_INSERTS,
  136.         NULL,
  137.         dw,
  138.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  139.         (LPTSTR) &lpMsgBuf,
  140.         0, NULL );
  141.  
  142.     // Display the error message.
  143.  
  144.     lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
  145.         (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) lpszFunction) + 40) * sizeof(TCHAR));
  146.     StringCchPrintf((LPTSTR)lpDisplayBuf,
  147.         LocalSize(lpDisplayBuf) / sizeof(TCHAR),
  148.         TEXT("%s failed with error %d: %s"),
  149.         lpszFunction, dw, lpMsgBuf);
  150.     MessageBox(NULL, (LPCTSTR) lpDisplayBuf, TEXT("Error"), MB_OK);
  151.  
  152.     // Free error-handling buffer allocations.
  153.  
  154.     LocalFree(lpMsgBuf);
  155.     LocalFree(lpDisplayBuf);
  156. }
Add Comment
Please, Sign In to add comment