C++ 在单独的线程中处理向量元素

C++ 在单独的线程中处理向量元素,c++,multithreading,parallel-processing,C++,Multithreading,Parallel Processing,我试图在单独的线程中处理向量的元素,并将结果放在不同的向量中。我试过使用互斥体和代码的关键部分,在这些部分中我检查并从输入向量中取出元素,但是当我运行代码时,我遇到了访问冲突 编辑:我已经更新了代码,将结果放回另一个关键部分的向量中,并在线程开始之前初始化向量 #include "stdafx.h" #include <windows.h> #include <stdlib.h> #include <string.h> #include <stdio.h

我试图在单独的线程中处理向量的元素,并将结果放在不同的向量中。我试过使用互斥体和代码的关键部分,在这些部分中我检查并从输入向量中取出元素,但是当我运行代码时,我遇到了访问冲突

编辑:我已经更新了代码,将结果放回另一个关键部分的向量中,并在线程开始之前初始化向量

#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 );   
}
#包括“stdafx.h”
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义最大线程数4
void InvertProc(void*MyID);//线程2到n:显示
无效关闭(无效);//程序关闭
int ThreadNr;//已启动的线程数
临界截面cs,cs2;
std::vector _-oTempVector;
std::vector_oOutVector;
国际柜台;
int _tmain(int argc,_TCHAR*argv[]
{     
ThreadNr=0;
OutCounter=0;
对于(int i=0;i<50000;i++){
_推回(i);
_oOutVector.push_back(0);
}
初始化关键部分(&cs);
初始化关键部分(&cs2);
向量事件;
对于(ThreadNr=0;ThreadNrstd::cout您的输出向量不在临界区内,它应该是一个共享对象。。。。
因为如果多个线程试图同时将_向后推,您将面临一场写-写-写数据竞赛

  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;
    }
 }
void InvertProc(void*pMyID)
{   
int threadnum=*((int*)pMyID);
int chunk=input.size()/THREAD\u NUM;
int start=threadnum*块;
int end=start+chunk;
对于(I=开始;I<结束;++I)
{
输出[i]=输入[i]*-1;
}
}

如果我把它放在同一个关键部分,得到的程序将不是真正并行的,只是多线程的,但它将按顺序运行。当然,在这种情况下,元素的处理(乘以-1)是一个简单的操作,但在现实生活中,对元素执行一个耗时的操作。我尝试将元素在外部向量中的推动放在另一个关键部分(cs2),但仍然不起作用。完全同意你的观点,但问题是“我为什么会遇到访问冲突”…关于并发性问题,请参阅我的答案中的一些更新!!!我已使用另一个关键部分更新了代码,但现在对于4个线程,它会导致死锁。对于死锁,它可能来自关键部分cs1,因为在if语句之前输入cs1,如果条件不正确,则永远不会离开cs1!好的,谢谢你,我没想到会这样!那么我应该在if之后进入临界区,还是在else的情况下也离开呢?我希望if处于临界区,因为否则另一个线程可能会消耗向量的所有元素,这将导致back/pop_back失败!