3

I have made a thread pool which writes to the same vector at the same time.

Is this implementation thread safe?

If it is not, how should I fix it?

std::vector<double> global_var;

void func1(int i)
{
    global_var[i]=some_computation(i /* only depends on i */);
}

void load_distribution()
{
    const int N_max=100;
    global_var.assign(N_max,0.0);
    std::vector<std::thread> th_pool;
    for(long i=0;i<N_max;i++)
        th_pool.push_back(std::thread(func1,i));

    for(std::thread& tp : th_pool)
        tp.join();
}

Update

global_var will not be touched by any other part of the program before all threads terminated.

ar2015
  • 5,558
  • 8
  • 53
  • 110
  • 1
    While I hate to admit, the current snippet is actually thread safe. ...Still, your design is really fragile. There may be another portion of your code that may modify `global_var` which will introduce Undefined Behavior – WhiZTiM Dec 29 '16 at 22:07
  • @WhiZTiM I guarantee, `global_var` will not be changed by any other part of the program before all threads terminate. – ar2015 Dec 29 '16 at 22:09
  • the complete code [here](http://pastebin.com/S3GYTYBf) for just in case. – ar2015 Dec 29 '16 at 22:16

3 Answers3

3

Assuming your global vector is not modified by any other part of code, then your code is thread safe.

Each thread is going to write (access) into a different cell of the vector, so there is no "dirty update" problem.

Moreover the vector's type is a double, in a modern architecture is bigger than a WORD-size. So each array cell is not overlapped among others.

BiagioF
  • 9,368
  • 2
  • 26
  • 50
  • Thank you very much. What if I use a `vector`. Can it make any problem? – ar2015 Dec 29 '16 at 22:17
  • @ar2015 Not if there memory is allocated in an aligned way – BiagioF Dec 29 '16 at 22:19
  • what is aligned way of memory allocation or what is an example of non-aligned way? – ar2015 Dec 29 '16 at 22:20
  • @ar2015 I've answer that question some months ago. If you want see [here](http://stackoverflow.com/questions/38875369/what-is-data-alignment-why-and-when-should-i-be-worried-when-typecasting-pointe/38875855#38875855) – BiagioF Dec 29 '16 at 22:22
  • As you are talking, if I use `vector` where `complicatedObj` contains several `vector`s itself, the code may fail. I am correct? – ar2015 Dec 29 '16 at 22:24
  • @ar2015 If each thread will access a different index, without any data-race and the memory is aligned, then there are no reasons the code should fail. Even with very complicated object. – BiagioF Dec 29 '16 at 22:26
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/131872/discussion-between-biagio-festa-and-ar2015). – BiagioF Dec 30 '16 at 07:12
3

[container.requirements.dataraces]/1-2:

1 For purposes of avoiding data races ([res.on.data.races]), implementations shall consider the following functions to be const: begin, end, rbegin, rend, front, back, data, [...], at and, except in associative or unordered associative containers, operator[].

2 Notwithstanding ([res.on.data.races]), implementations are required to avoid data races when the contents of the contained object in different elements in the same container, excepting vector<bool>, are modified concurrently.

T.C.
  • 133,968
  • 17
  • 288
  • 421
-1

Generally, std::vector is not thread safe, but the above code will work because the backing array is preallocated with assign() method.

As long as the writers don't cause reallocating the backing array, the code will work. The assign() method will preallocate enough space so it will not happen when the thread write to it.

Zbynek Vyskovsky - kvr000
  • 18,186
  • 3
  • 35
  • 43
  • actually, an assignment has already been used `global_var.assign(N_max,0.0);` – ar2015 Dec 29 '16 at 22:11
  • What if instead of `vector`, I use `vector` which will contain other vectors inside themselves. In this case, does assignment invalidate the vector? – ar2015 Dec 29 '16 at 22:14
  • @ar2015 : No, it wouldn't modify the outside vector, it would touch only the content of each element. And as the outside backing array wouldn't be modified, the modification of the particular elements would be thread safe. Of course, as long as there would be just single thread touching each of them. – Zbynek Vyskovsky - kvr000 Dec 29 '16 at 23:49