From: Chris M. Thomasson on
"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
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
"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
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
"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! ]