1

ベクトルの要素を別のスレッドで処理し、結果を別のベクトルに入れようとしています。ミューテックスと、入力ベクトルから要素をチェックして取り出すコードの周りのクリティカル セクションを試しましたが、コードを実行するとアクセス違反が発生します。

編集:コードを更新して、結果をベクトルの別のクリティカル セクションに戻し、スレッドが開始する前にベクトルを初期化しました。

#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <process.h>
#include <iostream>
#include <vector>

#define MAX_THREADS  4

void InvertProc( void * MyID );      // Threads 2 to n: display 
void ShutDown( void );               // Program shutdown 

int     ThreadNr;                    // Number of threads started 
CRITICAL_SECTION cs, cs2;

std::vector<int> _oTempVector;
std::vector<int> _oOutVector;

int OutCounter;

int _tmain(int argc, _TCHAR* argv[])
{     
   ThreadNr = 0;
   OutCounter = 0;

   for ( int i = 0; i < 50000; i++ ) {
      _oTempVector.push_back( i );
      _oOutVector.push_back( 0 );
   }

   InitializeCriticalSection( &cs );   
   InitializeCriticalSection( &cs2 ); 

   std::vector<HANDLE> events;
   for ( ThreadNr = 0; ThreadNr < MAX_THREADS; ThreadNr++ ) {            
      HANDLE handle = (HANDLE)_beginthread( InvertProc, 0, &ThreadNr );      
      events.push_back( handle );
   }

   WaitForMultipleObjects( events.size(), &events[0], true, INFINITE );  

   std::cout << "outvector contains:" << _oOutVector.size() << "elements"; 
   std::cout << '\n'; 
}


void InvertProc( void *pMyID )
{   
   do {
      EnterCriticalSection( &cs ); 
      if ( _oTempVector.size() > 0 ) {
         int iElement = _oTempVector.back();
         _oTempVector.pop_back();
         LeaveCriticalSection( &cs );

         iElement *= -1;

         EnterCriticalSection( &cs2 ); 
         _oOutVector[OutCounter] = iElement; 
         OutCounter++;
         LeaveCriticalSection( &cs2 );
      }
   } while ( _oTempVector.size() > 0 );   
}
4

1 に答える 1

0

あなたの出力ベクトルは共有オブジェクトとしてクリティカル セクション内にありません....複数のスレッドが同時に push_back を試みると、Write over Write Data レースが発生します!!!!

  EnterCriticalSection( &cs ); 
  if ( _oTempVector.size() > 0 ) {
     int iElement = _oTempVector.back();
     _oTempVector.pop_back();
          iElement *= -1;
     _oOutVector.push_back( iElement );   
     LeaveCriticalSection( &cs );
  }
 } while ( _oTempVector.size() > 0 );   

結果として実行中のスレッドは、同時に実行されるよりも順次実行されます

それを解決するには、別のことをしなければなりません:1)問題を分割できますか、各スレッドは入力ベクトルの連続する要素で動作する必要があります2)出力ベクトルが入力のサイズで最初に初期化された場合、すべてを削除しますプッシュによる問題!

実行中の各スレッドは、指定された範囲の数値を *-1 入力し、他のスレッドとの出力ベクトルの特定の場所に (相互作用なしで) 結果を配置するため、ロックを解除できます。

void InvertProc( void *pMyID )
{   
    int threadnum = *((int*)pMyID);
    int chunk = input.size()/THREAD_NUM;
    int start = threadnum*chunk;
    int end = start+chunk;
    for (I = start ; I < end ; ++I)
    {
        output[i] = input[i]*-1;
    }
 }
于 2013-07-15T06:13:44.113 に答える