C++ 为同一向量C+运行多个线程时出现分段错误+;

C++ 为同一向量C+运行多个线程时出现分段错误+;,c++,multithreading,c++11,mutex,C++,Multithreading,C++11,Mutex,有一个共享向量,其中包含由两个线程访问的数据。但在代码下面运行时。我遇到一个错误,提到分段错误(核心转储)。这里std::vector outputOfStealthAddresses是共享向量。这里我要做的是,每个线程都需要从向量中获取第一个值,并将其本地存储在线程中,然后将其从向量中删除(避免每个线程重复使用)。这里我使用了一个互斥锁来锁定向量。然后将本地存储的数据传递到SQLite连接,以将数据插入数据库 注意-这里我为每个线程使用两个SQLite连接 下面是两个线程函数 线程1函数 vo

有一个共享向量,其中包含由两个线程访问的数据。但在代码下面运行时。我遇到一个错误,提到分段错误(核心转储)。这里
std::vector outputOfStealthAddresses
是共享向量。这里我要做的是,每个线程都需要从向量中获取第一个值,并将其本地存储在线程中,然后将其从向量中删除(避免每个线程重复使用)。这里我使用了一个互斥锁来锁定向量。然后将本地存储的数据传递到SQLite连接,以将数据插入数据库

注意-这里我为每个线程使用两个SQLite连接

下面是两个线程函数

线程1函数

void runSaDataStoreThread1(){
    //creating sqlite connection
    indexMapper::indexes dbConnectionSA ("file", "sub-file","data" ,true );    //init database instance globally

    //create data table for tx details
    dbConnectionSA.createTable(saDetailTable);

    while (true){
        if(!outputOfStealthAddresses.empty()){
            std::vector<json> temp;
            mtx.lock();
                if(!outputOfStealthAddresses.empty()){
                    temp.push_back(outputOfStealthAddresses[0]);
                    outputOfStealthAddresses.erase(outputOfStealthAddresses.begin());
                }
            mtx.unlock();

            if(!temp.empty()){
                dbConnectionSA.insertSAData(temp[0]);
            }

            temp.erase(temp.begin());
        }else if(outputOfStealthAddresses.empty() && isAllBlockDone){
            break;
        }
    }
    dbConnectionSA.close();
}
void runSaDataStoreThread2(){
    //creating sqlite connection
    indexMapper::indexes dbConnectionSA1 ("file", "sub-file","data-2" ,true );    //init database instance globally

    //create data table for tx details
    dbConnectionSA1.createTable(saDetailTable);

    while (true){
        if(!outputOfStealthAddresses.empty()){
            std::vector<json> temp2;

            mtx.lock();
            if(!outputOfStealthAddresses.empty()){
                temp2.push_back(outputOfStealthAddresses[0]);
                outputOfStealthAddresses.erase(outputOfStealthAddresses.begin());
            }
            mtx.unlock();

            if(!temp2.empty()){
                dbConnectionSA1.insertSAData(temp2[0]);
            }

            temp2.erase(temp2.begin());
        }else if(outputOfStealthAddresses.empty() && isAllBlockDone){
            break;
        }
    }
    dbConnectionSA1.close();
}
int main(){
  auto thread11 = std::thread(parse::runSaDataStoreThread1);
  auto thread16 = std::thread(parse::runSaDataStoreThread2);

  thread11.join();
  thread16.join();
}

您需要使用互斥来保护对向量方法的所有调用。具体来说,
empty()
调用。

至于您的具体问题:

您需要使用互斥锁来锁定向量上的所有操作

至于你实际上似乎想要解决的问题: 我假设您想通过并行化来加速sqlite插入? 如果是:这不会解决您的性能问题。你应该做的是:
将插入作为单个事务处理。

阅读同步。我还看到分别使用向量
temp
temp2
的零点。它们只包含一个数据元素。此外,除了传递给db连接的参数外,这段代码在两个线程中几乎完全相同。您可以使用构造时提供的这些线程的参数,并删除一半代码。对globals的广泛使用当然也没有起到这么大的作用。正如其他地方提到的,数据谓词的保护很重要,但这里没有这样做。我只能想象线程将数据推送到向量中所做的事情。谢谢你的回复@你能指出密码中怀疑的地方吗?我怀疑整个密码。我甚至不知道这到底是为了什么。看起来您正试图在两个线程之间来回切换,每个线程都从向量中读取下一项。情况是否如此,是否如此,仍然是个谜。如果你不再把
outputOfStealthAddresses
看作一个向量,而是把它看作一个队列,这可能会更合理,但我不知道这是否是一个准确的描述。这具有向量对象的所有特性。请解释一下好吗?@sajitaliyanage,一个调用
outputOfStealthAddresses.empty()的线程如果另一个线程恰好在
擦除(…)
调用的中途,则该线程可以看到向量对象的内部处于不一致的状态。在这一点上可能会发生任何事情(例如,分段错误)。@YSC,james,谢谢。在向所有进程添加互斥后,我解决了这个问题。包括空()调用。:)