🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.c
Article #309636

Re: Jak najlepiej dzielić dane wspólne dla wątków?

#309636
From: Wojciech Muła
Date: Mon, 29 Jan 2018 17:57
83 lines
4294 bytes
On Monday, January 29, 2018 at 1:22:58 PM UTC+1, Borneq wrote:
> Mam gist:
> https://gist.github.com/borneq/f63cf132abef474dc9e25491d3115351
> void FinderForBlock::execute(vector<InputTx> *inputVec, vector<OutputTx> 
> *outputVec)
> {
>      FinderForTx finder;
>      for (size_t i = 0; i<inputVec->size(); i++)
>      {
>          outputVec->at(i) = finder.findPred(inputVec->at(i));
>      }
> }
> 
> vector<thread> vec_thr;
> for (int i=0; i<nThreads; i++)
>      vec_thr.emplace_back(&execute, &inputVec, &outputVec);
> for (auto& t : vec_thr)
>      t.join()
> 
> (pytałem się na 
> https://social.msdn.microsoft.com/Forums/en-US/37c1cf02-6a54-47d3-ba1c-a631239f81e8/how-to-share-thread-data?forum=vcgeneral 
> ale nie chcę TLS)
> 
> Chodzi o to, że execute dostaje jako parametry dwa wektory a ma jeszcze 
> dostać indeks wspólny i muteks, który ma nie być globalny.
> Kiedyś robiłem to tak, że definiowałem strukturę z muteksem, indeksem i 
> innymi rzeczami i dawałem wskaźnik na nią do wszystkich wątków:
> void FinderForBlock::execute(Structure *structure)
> {
>      FinderForTx finder;
>      while(true)
>      {
>        structure->mutex.lock();
>         if (structure->index>=structure->vecSizes)
>        {
>          structure->mutex.unlock();
>          break;
>        }
>        structure->index++;
>        structure->mutex.unlock();
>        outputVec->at(structure->index-1) = 
> finder.findPred(inputVec->at(structure->index-1));
>      }
> }
> 
> Czy sposób ze strukturą jest dobry? A zamiast niej chciałbym użyć klasy 
> FindeForBlock - jak?

Po pierwsze masz poważny błąd FinderForBlock::execute. W obrębie
mutexu zwiększasz index, ale po wyjściu z blokady czytasz to pole
i to dwa razy. Po mutex.unlock() inne wątki mogą zmienić index.

Poprawnie byłoby:

    structure->mutex.lock();
    if (structure->index>=structure->vecSizes)
    {
      structure->mutex.unlock();
      break;
    }
    const auto index = structure->index++;
    structure->mutex.unlock();
    outputVec->at(index) = finder.findPred(inputVec->at(index))

Ale ogólnie to nie potrzebujesz mutexa. Wątki mają działać na rozłącznych
zakresach wektorów, wiesz na ilu wątkach to robisz (masz nThreads, nie).
Wyznacz sobie zakresy dla każdego wątku i tyle. Wtedy metoda execute miałaby
postać:

void FinderForBlock::execute(vector<InputTx> *inputVec, vector<OutputTx> 
*outputVec, size_t start, size_t end)
{
     FinderForTx finder;
     for (size_t i = start; i < end; i++)
     {
         outputVec->at(i) = finder.findPred(inputVec->at(i));
     }
}

Tylko wyznaczanie zakresów wymaga trochę uwagi, bo jesteś w dziedzinie
liczb całkowitych.

w.
Technical Details
Message-ID: <ccc1fb76-71bd-49f2-a9bf-e210f9071e5c@googlegroups.com>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!news.nask.pl!news.nask.org.pl!news.unit0.net!weretis.net!feeder6.news.weretis.net!feeder.usenetexpress.com!feeder-in1.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!border2.nntp.dca1.giganews.com!nntp.giganews.com!i22no3290330qta.1!news-out.google.com!e39ni1108qtk.1!nntp.google.com!s47no3296682qta.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail
References: <p4n3n1$fom$1@node1.news.atman.pl>

Show Full Headers
Complete Article Headers
X-Received: by 10.200.23.173 with SMTP id o42mr17281346qtj.45.1517248657192;        Mon, 29 Jan 2018 09:57:37 -0800 (PST)
X-Received: by 10.31.160.5 with SMTP id j5mr2591764vke.6.1517248656994; Mon, 29 Jan 2018 09:57:36 -0800 (PST)
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!news.nask.pl!news.nask.org.pl!news.unit0.net!weretis.net!feeder6.news.weretis.net!feeder.usenetexpress.com!feeder-in1.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!border2.nntp.dca1.giganews.com!nntp.giganews.com!i22no3290330qta.1!news-out.google.com!e39ni1108qtk.1!nntp.google.com!s47no3296682qta.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail
Newsgroups: pl.comp.lang.c
Date: Mon, 29 Jan 2018 09:57:36 -0800 (PST)
In-Reply-To: <p4n3n1$fom$1@node1.news.atman.pl>
Complaints-To: groups-abuse@google.com
Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=2a01:112f:80d:ee00:d6be:d9ff:fe09:8928; posting-account=VFwkXwoAAADdT4-lLKRZrMYkTjizGoyn
NNTP-Posting-Host: 2a01:112f:80d:ee00:d6be:d9ff:fe09:8928
References: <p4n3n1$fom$1@node1.news.atman.pl>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <ccc1fb76-71bd-49f2-a9bf-e210f9071e5c@googlegroups.com>
Subject: Re: Jak najlepiej dzielić dane
 wspólne dla wątków?
From: Wojciech Muła <wojciech_mula@poczta.onet.pl>
Injection-Date: Mon, 29 Jan 2018 17:57:37 +0000
Lines: 95
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit