Friday, January 17, 2014

FeedaMail: Comments for Sutter’s Mill

feedamail.com Comments for Sutter's Mill

Comment on GotW #96: Oversharing by Bartosz Milewski

Question 2. Except for trivial cases, data has to be passed between threads. There are many ways to do it and some of them don’t require additional synchronization. I’m saying “additional” because there are two synchronization points in the life of every thread: its creation and its destruction.

So you can create data before you pass it to the thread constructor and, if you can guarantee that you won’t access it afterwards, the thread is free to use it without synchronization. Similarly, a thread may create and manipulate data before it returns it (e.g., through a future) to the caller. The best guarantee of non-access is provided by move semantics. When you move your data to the constructor of the thread, or move it back from the thread, you are guaranteed that there is only one thread at a time that can access it.

Another way to avoid synchronization is to use immutable data. In that case many threads may access the same data concurrently without synchronization. You have to make sure though that the data was created before the threads were started (or there is some other “happens before” edge between creation and use), because data creation almost always involves mutation.

Read More »

Comment on GotW #96: Oversharing by Bartosz Milewski

Question 3. If the variable is not physically shared, then threads won’t be able to see each other’s writes. But if that’s okay, then you can give each thread its own private copy to read and modify and then, at a later time, collect the results and merge them, a la map/reduce. Is that what you had in mind?

Read More »

Comment on GotW #95 Solution: Thread Safety and Synchronization by Paul Groke

Hi Herb, what do you mean by “concurrent const operations that are just reading from the same variable x must be safe”? That all const operations that are logically a clean “read” must be safe? I’m not sure that that’s a good definition.
On the one hand, it’s more complicated than it has to be. After all, what kind of const operations can (or should) be there that are not logically a clean “read”? So wouldn’t it be better to just say all const operations?
On the other hand it forbids stuff like lazy evaluation.
So for me this is somewhere in between “restrictive, but so simple that anyone can understand it and apply it correctly without having to think too much” and “a little complicated but allows us to do cool stuff that we otherwise couldn’t”.
So maybe the best thing would be to just document which methods are thread-safe and which are not.

Read More »

Comment on GotW #96: Oversharing by duhonedd

1) The primary problem is that it is too easy for a user of some_obj to forget, or not even realize that synchronization is required. Especially as a program gets very large. some_obj will be relying on a comment that programmers won’t read to inform them that synchronization is needed. On the plus side, by not embedding synchronization into some_obj’s class, you wont have to pay for it if you don’t need it on some_obj2.

2, 3) The main goal is to make sure users can’t accidently use a shared object without synchronization, and hopefully to at the same time not require it if another instance is used strictly internally somewhere that is already internally synchronized. It would also be nice if the maintainer of the class of some_obj didn’t have to think about synchronization, keep concerns separated. For this I like the handle body idiom. No classes provide synchronization directly, instead a family of thread safe handles can be used to wrap an instance in, when needed. We can also make use of this handle to cleanly synchronize when we need to make multiple calls to some_obj atomicly. Code is below.

    template&lttypename T&gt  class Shared  {  public:      void Lock(std::function&ltvoid (T& _instance)&gt _work)      {          std::lock_guard&ltstd::mutex7gt lock(m_mutex);          _work(m_instance);      }  private:      std::mutex m_mutex;      T m_instance;  };    Shared&ltFoo&gt some_obj;  some_obj.Lock([](auto _instance){      _instance.foo1();      _instance.foo2();  });    

Read More »
 
Delievered to you by Feedamail.
Unsubscribe

No comments:

Post a Comment