Prev: Dependent function templates and overloaded functions
Next: Fast Assignment of POD Struct Whose Members Have Copy Constructors
From: Chris M. Thomasson on 27 Dec 2009 07:38 "Branimir Maksimovic" <bmaxa(a)hotmail.com> wrote in message news:hh3ulb$hr6$1(a)news.albasani.net... > Chris M. Thomasson wrote: >> "Branimir Maksimovic" <bmaxa(a)hotmail.com> wrote in message >> news:hgs21l$pm0$1(a)news.albasani.net... >>> Andrew wrote: >>>> I am designing a system where an app will need to spawn a child thread >>>> then the child and parent thread will need to communicate. If this was >>>> in java I would use ConcurrentLinkedQueue but what to do in C++? I >>>> have googled and searched boost but cannot find anything. >>>> >>>> There is a class that would serve in ACE but ACE is huge so I do not >>>> want to introduce ACE to the project. The project is already using >>>> boost and fighting the battle for more boost usage is hard enough. >>>> >>>> Does anyone know if such a facility is planned for the upcoming std? >>> >>> I would advise against using threads. Processes and shared memory is >>> much more easier to maintain, >> >> I am curious as to what made you come to that conclusion? Anyway, which >> one >> is easier: Creating a dynamic unbounded queue with threads or shared >> memory >> and processes? > > Depends. You can always use cout and simple pipe. Why queue? For performance and scalability reasons. A pipe or socket has fairly significant overhead when compared to a clever shared memory based synchronization. I prefer to use lightweight synchronization primitives and I also know how to implement them. I am familiar with the caveats and realize that it's easier to create intra-process facilities. Keep in mind that I am writing this from the low-level implementation point of view. > When performance is concern vectorized operations on memory > parallel loops and such stuff have sense with threads. > There are many ways to do IPC... Indeed! :^) > Depending on situation. > For example I had case when server version that is php which > with popen starts c executable which returns result with printf and > initialize data with every request, performs > three times faster than java multithreaded > server as search engine... Unfortunately, that does not prove anything. > There is deque class in stdlib, it is good as queue, I use > it all the time... As I implied in the previous post, you _cannot_ use a `std::deque' _unless_ you can _ensure_ that every single process that wants to ever use the queue will map there personal view of shared memory at the _exact_ same base address as all the others. This is not always possible. Therefore, if you have experience with creating inter-process synchronization primitives you know to avoid pointers that the plague and always work in terms of offsets in order to completely solve the issue in all cases. > OP can lock it with os mutex he have and that;s it... I am sorry, but that's not "all" of it. For instance, what happens if a process dies while it's in the middle of mutating the deque? A `std::deque' is not robust, and cannot roll itself back and recover for this scenario. Keep in mind that it's normal for processes to die, unless you have strict control and know for a 100% fact that none of them will ever die prematurely. The OS provided inter-process mutex should have the ability to detect this. Think `WAIT_ABANDONED ' on Windows and 'EOWNERDEAD' on POSIX. On the other hand, threads should _never_ be randomly dieing in unexpected places. > Vector is also ok for this (push_back/back/pop_back), linked list etc... > > I don;t see problem here. There are many caveats. Not only do you have to keep offsets, you are also going to need to use a special allocator that works with a view of shared memory. > But since op asks this question, > probably he doesn;t know what is mutex... > That's why if he uses cout/pipe or sockets or something > else he will safe himself lot of maintenance problems... Granted, however I am focusing on performance and difficulty of implementation. If you were actually implementing a high-performance communication primitive, would it be easier to create an intra-process or a robust inter-process version? >> Why would you think that all that is easier than using threads? What am I >> missing here? > > Maintenance problems. With processes, there is no problem. > For example there is pre forked and pre threaded version > of apache. People prefer forked version because of libraries > they have to link in. On my machine mt server serves > more than 60000 thousand simple echo requests per second > with 28000 connections on single cpu, > which is far too much , you get rarely more than 100 requests per > second... Well, one thing that is nice with processes is that you can gracefully handle a buggy user plug-in that crashes. You isolate plug-in instances to a separate process-pool. When the watchdog process detects that a process in the pool has died, it can resurrect the process and everything's fine and the main application is still up and running. Therefore, I would _not_ use threads to handle a plug-in framework. I would use a single master process, a single watchdog process, and multiple user plug-in processes. [...] -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Branimir Maksimovic on 28 Dec 2009 03:10 Chris M. Thomasson wrote: > "Branimir Maksimovic" <bmaxa(a)hotmail.com> wrote in message > > > >> There is deque class in stdlib, it is good as queue, I use >> it all the time... > > As I implied in the previous post, you _cannot_ use a `std::deque' _unless_ > you can _ensure_ that every single process that wants to ever use the queue > will map there personal view of shared memory at the _exact_ same base > address as all the others. This is not always possible. Therefore, if you > have experience with creating inter-process synchronization primitives you > know to avoid pointers that the plague and always work in terms of offsets > in order to completely solve the issue in all cases. I'm using deque in combination with threads. That was meant for that. For processes and shared memory you are right and I agree. > > > > >> OP can lock it with os mutex he have and that;s it... > > I am sorry, but that's not "all" of it. For instance, what happens if a > process dies while it's in the middle of mutating the deque? Yes, these are all problems with processes/shared memory. > > > >> Vector is also ok for this (push_back/back/pop_back), linked list etc... >> >> I don;t see problem here. > > There are many caveats. Not only do you have to keep offsets, you are also > going to need to use a special allocator that works with a view of shared > memory. > I meant for threads. No need for special class. ACE/any other > > > >> But since op asks this question, >> probably he doesn;t know what is mutex... >> That's why if he uses cout/pipe or sockets or something >> else he will safe himself lot of maintenance problems... > > Granted, however I am focusing on performance and difficulty of > implementation. If you were actually implementing a high-performance > communication primitive, would it be easier to create an intra-process or a > robust inter-process version? You have argument. Threaded version is easier to write. > > > > >>> Why would you think that all that is easier than using threads? What >>> am I >>> missing here? >> >> Maintenance problems. With processes, there is no problem. >> For example there is pre forked and pre threaded version >> of apache. People prefer forked version because of libraries >> they have to link in. Therefore, I would _not_ use > threads to handle a plug-in framework. I would use a single master process, > a single watchdog process, and multiple user plug-in processes. > > [...] > That is what Im talking about. Problem is that I wrote cmd handler, which other programmers use to write commands. Something like rpc. Once I got emergency call when I was in bus on road to Barcelona on holiday, because one of programmers linked in non thread safe library, and online servers started to have problems. Thanks god on Internet cafes and ssh ;) Greets -- http:/maxa.homedns.org/ [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Chris M. Thomasson on 29 Dec 2009 12:49 "Branimir Maksimovic" <bmaxa(a)hotmail.com> wrote in message news:hh9rgr$3ac$1(a)news.albasani.net... > Chris M. Thomasson wrote: >> "Branimir Maksimovic" <bmaxa(a)hotmail.com> wrote in message >> >> >> >>> There is deque class in stdlib, it is good as queue, I use >>> it all the time... >> >> As I implied in the previous post, you _cannot_ use a `std::deque' >> _unless_ >> you can _ensure_ that every single process that wants to ever use the >> queue >> will map there personal view of shared memory at the _exact_ same base >> address as all the others. This is not always possible. Therefore, if you >> have experience with creating inter-process synchronization primitives >> you >> know to avoid pointers that the plague and always work in terms of >> offsets >> in order to completely solve the issue in all cases. > > I'm using deque in combination with threads. That was meant for that. > For processes and shared memory you are right and I agree. [...] Okay. As for STL deque, I personally prefer intrusive data-structures. Here is sketch for a queue: <pseudo-code in news reader> ___________________________________________________________ struct node { node* m_next; }; struct queue { node* m_head; // = NULL node* m_tail; void push(node* n) { if (! m_head) { m_head = n; } else { m_tail->m_next = n; } m_tail = n; } node* pop() { node* n = m_head; if (n) { m_head = n->m_next; } return n; } }; ___________________________________________________________ IMVHO, there is no "need" for dynamic allocation for something as simple as a FIFO. The interface allows the user to provide memory management. The nodes could reside on the "stack" of the calling thread, or the caller could use dynamic allocation. Not sure why something as simple as a queue should be required to handle node allocation, why a special node allocator for a simple queue? Why not let the user arrange and manage memory accordingly? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: yeroen on 29 Dec 2009 12:43 On Dec 8, 9:19 pm, Andrew <marlow.and...(a)googlemail.com> wrote: > I am designing a system where an app will need to spawn a child thread > then the child and parent thread will need to communicate. If this was > in java I would use ConcurrentLinkedQueue but what to do in C++? I > have googled and searched boost but cannot find anything. Herb Sutter, building on earlier work of Petru Marginean, authored a series of articles in Dr. Dobbs containing a complete C++ implementation of a lock-free concurrent queue: http://www.ddj.com/cpp/210600279 http://www.ddj.com/hpc-high-performance-computing/210604448 http://www.ddj.com/cpp/211601363 The implementation depends on the availability of the std::atomic<> template, which may or may not be provided by your current working compiler. Intel TBB also provides an tbb::atomic<> template. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Chris M. Thomasson on 31 Dec 2009 02:07 "yeroen" <gmrehbein(a)gmail.com> wrote in message news:bf4fda3b-e4d4-4f12-9f2c-a65fe9aa616a(a)k9g2000vbl.googlegroups.com... > On Dec 8, 9:19 pm, Andrew <marlow.and...(a)googlemail.com> wrote: >> I am designing a system where an app will need to spawn a child thread >> then the child and parent thread will need to communicate. If this was >> in java I would use ConcurrentLinkedQueue but what to do in C++? I >> have googled and searched boost but cannot find anything. > > Herb Sutter, building on earlier work of Petru Marginean, > authored a series of articles in Dr. Dobbs containing a complete C++ > implementation of a lock-free > concurrent queue: [...] FWIW, here is a decent algorithm for a wait-free single producer/consumer queue: http://thread.gmane.org/gmane.comp.lib.boost.devel/197400 (IMO, it's probably good to read the entire thread...) You can use eventcounts for conditional blocking. IIRC, the code by Petru used a timed wait on a condition variable which I consider to be sort of "hackish" in nature. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: Dependent function templates and overloaded functions Next: Fast Assignment of POD Struct Whose Members Have Copy Constructors |