多线程应用程序,我做得对吗?

时间:2012-10-10 03:37:02

标签: c++ arrays multithreading

这是在一个数组上做4个线程,然后将该数组分配给累积计数?我相信它是。我知道rand()不是线程安全的,一旦我知道逻辑是正确的,我就会改变它。

这是对一些建议的恭维 Problems passing array by reference to threads 然后 c++ multithread array

我知道这不是练习最佳练习方法,但我只是想让它运行起来。

我认为我让它正常运行,不得不将for for counter变量从x更改为p,不知道为什么......也将fHolder移出for循环。

我的fholder总是0,我不知道为什么。我检查了反...的价值。

#include <process.h>
#include <windows.h>
#include <iostream>
#include <fstream>
#include <time.h>
//#include <thread>

using namespace std;

void myThread0 (void *dummy );
void myThread1 (void *dummy );
void myThread2 (void *dummy );
void myThread3 (void *dummy );

//only needed for shared variables
//CRITICAL_SECTION cs1,cs2,cs3,cs4; // global

int main()
{

    //InitializeCriticalSection(&cs1);
    //InitializeCriticalSection(&cs2);
    //InitializeCriticalSection(&cs3);
    //InitializeCriticalSection(&cs4);

    ofstream myfile;
    myfile.open ("coinToss.csv");

    int rNum;

    long numRuns;
    long count = 0;
    int divisor = 1;
    float fHolder = 0;
    long counter = 0;
    float percent = 0.0;


    //?
    unsigned threadID;

    //HANDLE hThread;
    HANDLE hThread[4];

    const int size = 100000;

    int array[size];

    srand ( time(NULL) );

    printf ("Runs (uses multiple of 100,000) ");
    cin >> numRuns;

    for (int a = 0; a < numRuns; a++)
     {

            hThread[0] = (HANDLE)_beginthread( myThread0, 0, (void*)(array) );
            hThread[1] = (HANDLE)_beginthread( myThread1, 0, (void*)(array) );
            hThread[2] = (HANDLE)_beginthread( myThread2, 0, (void*)(array) );
            hThread[3] = (HANDLE)_beginthread( myThread3, 0, (void*)(array) );

            //waits for threads to finish before continuing
            WaitForMultipleObjects(4, hThread, TRUE, INFINITE);

            //closes handles I guess?
            CloseHandle( hThread[0] );
            CloseHandle( hThread[1] );
            CloseHandle( hThread[2] );
            CloseHandle( hThread[3] );

        //dump array into calculations
        //average array into fHolder

            for (int p = 0; p < size; p++)
             {
                counter += array[p] == 2 ? 1 : -1;
                //cout << counter << endl;
                //cout << count << endl;
                //cout << p << endl;
                counter = count + counter;

                //divide into an exportable value
                //divides by 1,000,000, because each thread handles 250,000
                //cout << "Value " << x << ": " << array[x] << endl;
            }
            fHolder = counter / size;


        cout << "Final Count: " << counter << endl;
        cout << "fHolder: " << fHolder << endl;
        myfile << fHolder << endl;


    }



}
void myThread0 (void *param)
{
    //EnterCriticalSection(&cs1); //aquire the critical section object

    int *i = (int *)param;

    for (int x = 0; x < 25000; x++)
    {
        i[x] = rand() % 2 + 1;
        //cout << i[x] << endl;
    }
    //LeaveCriticalSection(&cs1); // release the critical section object

}

void myThread1 (void *param)
{
    //EnterCriticalSection(&cs2); //aquire the critical section object

    int *i = (int *)param;

    for (int x = 25000; x < 50000; x++)
    {
        //param[x] = rand() % 2 + 1;
        i[x] = rand() % 2 + 1;
        //cout << i[x] << endl;
    }
    //LeaveCriticalSection(&cs2); // release the critical section object

}

void myThread2 (void *param)
{
    //EnterCriticalSection(&cs3); //aquire the critical section object

    int *i = (int *)param;

    for (int x = 50000; x < 75000; x++)
    {
        i[x] = rand() % 2 + 1;
        //cout << i[x] << endl;
    }
    //LeaveCriticalSection(&cs3); // release the critical section object

}

void myThread3 (void *param)
{
    //EnterCriticalSection(&cs4); //aquire the critical section object

    int *i = (int *)param;

    for (int x = 75000; x < 100000; x++)
    {
        i[x] = rand() % 2 + 1;
        //cout << i[x] << endl;
    }
    //LeaveCriticalSection(&cs4); // release the critical section object

}

1 个答案:

答案 0 :(得分:1)

  1. _beginthread存在问题,您应该使用_beginthreadex。阅读这个新功能的文档,了解如何使用它。
  2. hThread是4个句柄的数组,因此在调用WaitForMultipleObjects时应该有4个而不是1个,并且应该有四个调用CloseHandle来关闭所有四个句柄。
  3. 考虑重命名该变量ahThread(a表示数组)或rghThread(rg表示范围)。
  4. 所有四个线程都在运行自己的数据。并且您拥有在实际使用这些数据之前故意等待所有四个线程完成的代码。这意味着您不需要四个关键部分中的任何一个。两个线程不会同时读取和写入某些数据。
  5. 这些关键部分使用错误。在代码中只有一个位置输入临界区是没有意义的,因为CS的目的是防止在CS下的当前代码执行时执行其他一些代码。在使用CS1的代码中只有一个位置,只有一个位于使用CS2的位置,依此类推。只需删除它们,因为如(4)中所述,您实际上并不需要它们。
  6. 标准输出是由其内部关键部分保护的单个资源,并在所有四个线程中使用。因此,所有四个线程都被强制在线cout << i[x] << endl;上同步,因此运行速度比必要的慢。
  7. cout << i[x] << endl;的问题在于它不是原子操作,它由四个线程同时运行。一个线程可能在另一个线程的i[x]endl的着作之间写下它的整行,这将产生不希望的结果。我会完全从线程中删除cout
  8. 在问题的当前版本(修订版3)中存在一个错误,for循环在CloseHandle之后过早结束。循环应该包含进行计数的内部循环。
  9. 与线程无关,但请考虑这行代码而不是当前存在的九行代码:counter += array[x] == 2 ? 1 : -1;。此处不需要变量count
  10. 所有四个线程都运行相似的代码。考虑使用参数param作为指向为此线程指定的数组部分开头的指针。这将允许您只有一个由四个线程运行的函数,其中所有四个线程的参数值都不同。