-1

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

这是一些关于通过引用线程传递数组 然后 是c++多线程数组的问题的一些建议的集合

我知道这不是在练习最佳实践方法,但我只是试图让它启动并运行。

我想我让它运行正确,不得不将一个 for 计数器变量从 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

}
4

1 回答 1

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. line 的问题cout << i[x] << endl;在于它不是原子操作,它由四个线程并发运行。i[x]一个线程可能会在另一个线程的写入和写入之间写入整行endl,这将产生不希望的结果。我会cout完全从线程中删除。
  8. 在问题的当前修订版(修订版 3)中存在一个错误,for 循环在 CloseHandle 之后过早结束。该循环应包含进行计数的内部循环。
  9. 与线程无关,但考虑这行代码而不是当前存在的九行代码:counter += array[x] == 2 ? 1 : -1;. count这里不需要变量。
  10. 所有四个线程都运行相当相似的代码。考虑将参数param用作指向为此线程指定的数组部分开头的指针。这将允许您只有一个由四个线程运行的函数,所有四个线程的参数值都不同。
于 2012-10-13T00:43:19.657 回答