Поток c предотвращает изменение значения

#c #multithreading #boost #mutex

#c #многопоточность #повышение #мьютекс

Вопрос:

Я использую boosthread для создания 3 потоков, каждый раз вызывающих одну и ту же функцию с разными передаваемыми аргументами. Например, 1/ thread.add(функция, int a1, std::string b), thread.add (функция, int a2, std::string b), thread.add (функция, int a3, std::string b), thread.add (функция, int a4, std::string b)

При изменении глобального значения в потоке я не хочу, чтобы другие потоки выполняли и снова изменяли значение, например, функция (a, b){

если (что-то произошло для этого потока) значение = 5;

//если ничего не произошло, значение = 1; }

Если один поток получает значение 5, то я не хочу, чтобы другие потоки вмешивались в это значение и возвращали его к 1. Как я могу это сделать? Спасибо.

Возможно, способ сделать это — использовать boost: mutex, но я не вижу в этом никакой выгоды, потому что это значение находится непосредственно перед оператором return, и я вполне мог бы использовать boost join_all() . Но это было бы менее эффективно.

Комментарии:

1. Попробуйте поместить измененное значение в очередь. При вставке убедитесь, что оно еще не существует в очереди, если оно существует, отбросьте вновь полученное значение, таким образом, вы получите значение, которое не должно быть изменено, и обратите внимание, что очередь должна находиться внутри заблокированных операторов, т.е. мьютекса

2. np mate. Надеюсь, у вас это сработало.

Ответ №1:

У меня есть один пример, который поможет вам. Он использует C 11, но может быть легко перенесен для ускорения.

алгоритм прост, он состоит из двух основных частей:

  1. Запускает три потока
  2. Присоединяется к ним (ожидает их завершения)

Что делает каждый поток:

  1. Выполняет ли какая-то работа
  2. Инициализирует переменную, если она никогда не была инициализирована ранее (FirstThreadToFinish)

Как работает уникальная функция инициализации. 1. использует мьютекс для предотвращения множественного доступа к общим переменным (гарантирует, что к этой функции одновременно может обращаться только один поток) 2.Если переменные не были инициализированы, он инициализирует их именем потока и присваивает логическому значению значение true (переменная инициализирована) 3. в противном случае ничего не делает

 #include "stdafx.h"
#include <thread>
#include <chrono>
#include <mutex>
#include <iostream>
#include <string>
using namespace std;

mutex m;//to synchronize the data properly
string FirstThreadToFinish;
bool IsInitialized;

//This function is called by the main thread: does the work and initializes the variable only once
int MyThreadFunction(int Duration, const string amp; ThreadName);

//this function does some work (put here what your thread is really supposed to do)
int DoSomeWork(int Duration);

//this function initializes the variable only once and does nothing otherwise
int InitializeVariableOnce(int Duration, const string amp; ThreadName);

//this function initializes the variable only once and does nothing otherwise
int InitializeVariableOnce(int Duration, const string amp; ThreadName)
{
    std::lock_guard<mutex> l(m);
    if (!IsInitialized)
    {
        FirstThreadToFinish=ThreadName;
        IsInitialized=true;
        cout<<"FirstThreadToFinish= "<<ThreadName<< ", IsInitialized= "<<IsInitialized<<endl;
    }
    return 0;
}

//this function does some work (put here what your thread is really supposed to do)
int DoSomeWork(int Duration)
{
    std::this_thread::sleep_for(std::chrono::seconds(Duration));
    return 0;
}

int MyThreadFunction(int Duration, const string amp; ThreadName)
{
    DoSomeWork(Duration);
    InitializeVariableOnce(Duration, ThreadName);
    return 0;
}

int main()
{
    //at the begining nothing is initialized
    FirstThreadToFinish="Uninitialized";
    IsInitialized=false;
    cout<< "FirstThreadToFinish= "<<FirstThreadToFinish << ", IsInitalized="<<IsInitialized<<endl; 

    cout<<"Now launching 3 threads= "<<endl;
    thread MyAThread(MyThreadFunction,1,"AThread");
    thread MyBThread(MyThreadFunction,2,"BThread");
    thread MyCThread(MyThreadFunction,3,"CThread");


    MyAThread.join();
    MyBThread.join();
    MyCThread.join();

    return 0;
}
  

Надеюсь, это поможет, не стесняйтесь сообщать мне, если не отвечает на вопрос