2013-07-15 37 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)如果輸出向量在輸入大小的初始位置初始化,則刪除由於推送造成的所有問題!

每個正在運行的線程將* -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; 
    } 
} 
+0

如果我把它放在同一個關鍵部分,所得到的程序將不是真正的並行,只是多線程的,但它會順序運行。當然在這種情況下,元素的處理(與-1相乘)是一個簡單的動作,但在現實生活中,對元素執行耗時的操作。我已經嘗試了將外部向量中的元素推入不同的關鍵部分(cs2),但它仍然無效。 – rufusz

+0

完全同意你,但問題是「爲什麼我得到訪問衝突」...對於併發問題,請參閱我的答案中的一些更新! – alexbuisson

+0

我已經用另一個關鍵部分更新了代碼並且沒有push_back,但是現在對於4個線程來說它會導致死鎖。 – rufusz