2013-07-15 3 views
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); 
} 

답변

0

여러 스레드가 동시에와 push_back하려고하면, 당신은 데이터 쓰기 경주를 통해 쓰기에 직면 때문에 출력 벡터가 정상적으로 공유 객체 .... 으로 임계 영역에 있지! !! !!

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) 출력 벡터가 입력의 크기로 처음에 초기화되면 푸시로 인한 모든 문제가 제거됩니다! 잠을

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; 
    } 
} 
+0

경우를 제거 할 수 있도록

각 실행 스레드 * -1 수가 소정 범위의 입력 다른 스레드 (상호 작용 없음)의 출력 벡터의 특정 장소에 결과를 넣어 똑같은 중요한 섹션에 넣으면 결과 프로그램이 실제로는 병렬 처리되지 않고 멀티 스레드로 처리되지만 순차적으로 실행됩니다. 물론이 경우 엘리먼트 처리 (-1로 곱하기)는 간단한 액션이지만 실생활에서는 엘리먼트에 시간 소모적 인 연산이 수행됩니다. 다른 핵심 섹션 (cs2)에있는 외부 벡터의 요소를 밀어 넣으려고했으나 여전히 작동하지 않았습니다. – rufusz

+0

전적으로 당신과 동의하지만, 질문은 "왜 나는 접근 위반을하고 있습니까?"... 동시성 문제에 대한 대답은 내 대답을 참조하십시오 !!! – alexbuisson

+0

코드를 다른 중요한 섹션과 push_back없이 업데이트했지만 이제는 4 개의 스레드에 대해 교착 상태가 발생합니다. – rufusz

관련 문제