简体   繁体   中英

C++ multithreading interruptions

As you can see in the main function I've created a group of threads that execute the exact same function yet with different parameters. The function simply prints out vector's values. Now the problem is that these threads interfere with one another. What I mean is that one thread does not finish printing (cout) before another starts, and it goes like sdkljasjdkljsad. I want some sort of chaotic order, such as, for example:

Thread 1 Vector[0]
Thread 2 Vector[0]
Thread 1 Vector[1]
Thread 3 Vector[0]
Thread 4 Vector[0]
Thread 2 Vector[1]

Rather than:

Thread 1 Thread 2 Vector[0] Vector[0]
Thread 2 Vector[1]
Thread 1 Thread 4 Vector[1] Thread 3 Vector[0] Vector[1]

How can I solve this problem? PS Data file is simply a list of player names, weight and bench-press per line. Transforming these to strings and placing in a vector (yeah, sounds dumb, but I'm just fulfilling a task).

#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <string>
#include <thread>
#include <sstream>
#include <iomanip>
#include <boost/thread.hpp>
#include <boost/bind.hpp>


using namespace std;

 vector<string> Kategorijos;
 vector< vector<string> > Zaidejai;
 ifstream duom("duom.txt");

 string precision(double a) {
     ostringstream out;
     out << setprecision(6) << a;
     return out.str();
 }

void read() {
    string tempKat;
    int tempZaidSk;
    vector<string> tempZaid;

    string vardas;
    int svoris;
    double pakeltasSvoris;
    while (duom >> tempKat >> tempZaidSk) {

        Kategorijos.push_back(tempKat);
        for (int i = 0; i < tempZaidSk; i++) {

            duom >> vardas >> svoris >> pakeltasSvoris;
            tempZaid.push_back(vardas + " " + to_string(svoris) + " " + precision(pakeltasSvoris));
        }
        Zaidejai.push_back(tempZaid);
        tempZaid.clear();
    }
    duom.close();
}


void writethreads(int a) {
    int pNr = a+1;
    for (int i = 0; i < (int)Zaidejai[a].size(); i++) {
        cout << endl << "Proceso nr: " << pNr << " " << i << ": " << Zaidejai[a][i] ;
    }
}

void print() {
    for (int i = 0; i < (int)Kategorijos.size(); i++) {
        cout << "***   " << Kategorijos[i] << "   ***" << endl;
        for (int j = 0; j < (int)Zaidejai[i].size();  j++) {
            cout << j+1<<") "<< Zaidejai[i][j] << endl;
        }
        cout << endl;
    }
    cout << "-------------------------------------------------------------------" << endl;
}

int main()
{   
    read();
    print();

    boost::thread_group threads
        ;
    for (int i = 0; i < (int)Kategorijos.size(); i++) {

        threads.create_thread(boost::bind(writethreads, i));

    }

    threads.join_all();

    system("pause");
    return 0;
}

Welcome to the problem of thread synchronization! When only one thread can use a resource at a time, the lock you use to control that resource is a mutex. You can also store the data for one thread to output at the end, or you can have the threads synch up at a barrier.

You can synchronise them, the console writes, with an appropriate mutex. But in this case, with the console output, maybe don't use threads at all. Else send the printing to a dedicated thread that deals with it.

The alternative to using the usual cout overloaded operator << is to write the content to a local buffer or stringsteam (including the new line) and then, with a single function call, write that to the console . The single function call will assist in the console writer only writing one buffer's contents at a time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM