Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

some issue w.r.t. pthread_cond_signal( )

20 views
Skip to first unread message

Pallav singh

unread,
Oct 24, 2008, 4:37:40 AM10/24/08
to
Hi

i am getting some issue w.r.t. pthread_cond_signal(&pr->condvar); &
pthread_cond_wait(&pq->condvar, &pq->mutexvar); ......some time
signaling is Not Happeing properly

Kindly give urs Suggestion

Thanks
pallav


+++++++++++++++++++++++++++++++++++++++++++++
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/errno.h>
#include <sys/signal.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <pthread.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#include <map>
#include <iostream>
#include <iterator>


#define PORT 21435
#define BACKLOG 5
#define NUM_THREADS 6
#define KEY 4321
#define PERMS 0660
#define MSGLEN 1024

using namespace std;

int errno;
int msgqid = -1;
pthread_t Thread_id;
pthread_attr_t attr;

typedef struct {
long int mesg_type;
char mesg_data[1024];
}Mesg;


class Childdata{
public :
int msgqid;
long Thread_id;
pthread_mutex_t mutexvar;
pthread_cond_t condvar;

Childdata(int ID):msgqid(ID){
Thread_id = 0;
pthread_mutex_init(&mutexvar , NULL);
pthread_cond_init(&condvar ,NULL);
}

~Childdata(){
pthread_cond_destroy(&condvar);
pthread_mutex_destroy(&mutexvar);
}
};

map<int,Childdata* > LooKUpTable;

void * SlaveThread(void * arg);
void * MasterThread(void * arg);
int sendall(int s, char *buf, int len);
void AddtoLookUpTable(int fd ,Childdata *data);
Childdata * findChildData(int id);
void RemovefromLookUpTable(int fd );


//Does Map Maintain Its own Local Copy of Data
//Yes... Default allocator is heap for STL
void AddtoLookUpTable(int fd ,Childdata *data){
pair<map<int,Childdata* >::iterator,bool> ret;
LooKUpTable.insert(pair<int,Childdata* >(fd,data));
}


void RemovefromLookUpTable(int fd ){
LooKUpTable.erase(fd);
}


Childdata * findChildData(int id){
return LooKUpTable.find(id)->second;
}


void mesg_send(int fd ,Mesg * msg){
msgsnd(fd ,(void *&)msg ,strlen(msg->mesg_data) + 1 ,IPC_NOWAIT);
}

void mesg_recv(int fd ,int msgtype ,Mesg * msg){
msgrcv( fd ,(void *)msg , MSGLEN, msgtype, IPC_NOWAIT);
}

void * MasterThread(void * arg)
{
int server_fd, child_fd;
socklen_t client_addr_size;
struct sockaddr_in server_addr,client_addr;

int fd_max, ret ,yes =1;
fd_set master ,read_fds,write_fds;

FD_ZERO(&master);
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);

server_fd = socket(AF_INET,SOCK_STREAM, 0);
setsockopt(server_fd ,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int));

server_addr.sin_family = AF_INET ; // Host Byte Order
server_addr.sin_port = htons(PORT); // Network Byte Order
server_addr.sin_addr.s_addr = INADDR_ANY; // Network Byte Order
memset(&(server_addr.sin_zero),'\0',8); // Fill Rest of Struct
with Zero

if( bind(server_fd,(struct sockaddr *)&server_addr,sizeof(struct
sockaddr))== -1)
{
perror(" bind fail -----");
exit(1);
}

listen(server_fd,BACKLOG);
fd_max = server_fd;

FD_SET(server_fd ,&master);

key_t mkey;
mkey=ftok(".",'z');

if((msgqid = msgget(mkey,PERMS|IPC_CREAT)) == -1)
{
cout << "Failed to create message queue" << endl;
exit(-1);
}
printf("server :: Created message queue with Id %d \n",msgqid);
printf("Inside MasterThread \n");

while(1)
{
int fd;
read_fds = write_fds = master ;

// select is Moving to Block state if it recieve a signal
if(( fd = select(fd_max +1,&read_fds,&write_fds,NULL,NULL))== -1 )
{
if(errno == EINTR )
continue ;
}

for(int i = 0 ;i <= fd_max; i++ )
{
if(FD_ISSET(i ,&read_fds))
{
if(i == server_fd)
{

client_addr_size = sizeof(struct sockaddr_in );
if((child_fd =accept(server_fd,(struct sockaddr
*)&client_addr ,
&client_addr_size)) == -1)
{
continue;
}

Childdata *pq = new Childdata(msgqid);
AddtoLookUpTable(child_fd, pq );

printf("Got new Connection from %s
\n",inet_ntoa(client_addr.sin_addr));
pthread_create( &Thread_id, &attr, SlaveThread, (void
*)&child_fd);

FD_SET(child_fd ,&master);

if(fd_max < child_fd)
{fd_max = child_fd;}

}
else
{
// find ThreadID where we need it send Data
// Use Child-fd as Delimeter to communicate over Message Queue
char buffer[1024] = {0};
int byte_count = 0;
Mesg serverMsg = {0};

if((byte_count = recv(i ,buffer,sizeof(buffer),0))<= 0)
{
cout << "Connection Closed by Client / Error \n";
if(byte_count == 0)
{
cout <<"Connection Got closed By Client \n";
close(i);
FD_CLR(i,&master);
Childdata *pr = findChildData(i);
cout<<"Remove Slave Thread "<< pr->Thread_id <<'\n';
pthread_cancel(pr->Thread_id);
RemovefromLookUpTable(i);
continue;
}
else
{perror(" recv ");}
}

Childdata *pr = findChildData(i);
pthread_mutex_lock(&pr->mutexvar);

serverMsg.mesg_type = i ;
strcpy(serverMsg.mesg_data,buffer);
printf("Master to Child Thread :: data to FD %d :: %s
\n",i, serverMsg.mesg_data);
mesg_send(msgqid,&serverMsg);

//pthread_mutex_unlock(&pr->mutexvar);
pthread_cond_signal(&pr->condvar);

}
}
}

}
return NULL;
}


void * SlaveThread(void * data)
{
int socket_fd = *(int *)data;
int mesg_type = socket_fd;
unsigned long Thread_id = pthread_self();

char buffer[1024] = {0};
Mesg recvMsg;

printf("Value of Slave thread id is %x \n",Thread_id);
Childdata *pq = findChildData(socket_fd);
pq->Thread_id = Thread_id;


pthread_mutex_lock(&pq->mutexvar);
cout << "before wait" << endl;
pthread_cond_wait(&pq->condvar, &pq->mutexvar);
cout << "after wait" << endl;

mesg_recv(pq->msgqid ,mesg_type ,&recvMsg);
pthread_mutex_unlock(&pq->mutexvar);

printf("Child fd %d :: Thread_id %d :: data Received:%s
\n",socket_fd,
Thread_id,recvMsg.mesg_data);
sprintf(buffer ,"Child fd %d :: Thread_id %d :: data send :: %s
\n",
socket_fd, Thread_id ," SERVER SEND DATA TO CHILD \0\n");

send(socket_fd ,buffer,strlen(buffer) + 1,0);

while(1);
//close(socket_fd);
//pthread_exit(NULL);

return NULL;
}


int main()
{
int rc;
printf("In main: creating Master Thread \n");
LooKUpTable.clear();

pthread_attr_init(&attr);
pthread_create( &Thread_id , &attr , MasterThread, NULL);

while(1);

pthread_attr_destroy(&attr);
pthread_exit(NULL);

return 0;
}

Markus Elfring

unread,
Oct 24, 2008, 5:37:14 AM10/24/08
to
> i am getting some issue w.r.t. pthread_cond_signal(&pr->condvar); &
> pthread_cond_wait(&pq->condvar, &pq->mutexvar); ......some time
> signaling is Not Happeing properly

Would you like to complete error detection and corresponding exception handling
in your approach?
How do you think about to reuse any well-known class library?

Regards,
Markus

Dave Butenhof

unread,
Oct 24, 2008, 7:40:47 AM10/24/08
to
Pallav singh wrote:
>
> i am getting some issue w.r.t. pthread_cond_signal(&pr->condvar); &
> pthread_cond_wait(&pq->condvar, &pq->mutexvar); ......some time
> signaling is Not Happeing properly

In fact, from your code, it's clear that signaling (or, more correctly,
waiting) is not EVER happening properly. But if you fix that bug, your
code might work as you intend.

A condition variable requires a shared data predicate, and the semantics
of POSIX condition variable operations require that you check and
confirm your shared data predicate in a loop. For example,

pthread_mutex_lock(&mutex);
while (!predicate) {
pthread_cond_wait(&cv, &mutex);
}
// do something under lock
pthread_mutex_unlock(&mutex);

The way you've coded it, depending on the timing of threads, your wait
may "hang" forever (it waits even when the predicate is already
satisfied and the "master" may never have any reason to signal again),
or it may return spuriously when the predicate remains unsatisfied (for
arcane and generally unlikely reasons, but your code is still incorrect
if it doesn't account for this).

I also question that you've commented the pthread_mutex_unlock() call in
your Master code. I don't see any other unlock, and your code is not
going to behave well without it.

Szabolcs Ferenczi

unread,
Oct 24, 2008, 1:43:18 PM10/24/08
to


You fall into the mistake that you are trying to use the condition
variable as if it were a semaphore. Though, you are not the only one
committing this mistake.

At the user level you want to communicate an event from one thread to
the other, don't you? The semaphore is a perfect software tool for
this. You can replace your mutex-condition variable pair with a
semaphore and then you can keep the waiting and signalling like you
use it now.

The other option is that you must introduce an additional shared
variable, a flag, and set-check that flag. Then you must protect the
shared flag with a mutex and you can optimise the waiting with the
condition variable as indicated for you here:

http://groups.google.com/group/comp.programming.threads/msg/96adb7210d95d41d

As I mentioned you are not the only one falling into the same trap.
See my detailed answer to an earlier case where I show the two
alternative solutions, i.e. the solution with the semaphore and with
condition variable:

http://groups.google.com/group/comp.programming.threads/msg/4a404e8ec93303d5

You can adapt it to your own case.

Best Regards,
Szabolcs

David Schwartz

unread,
Oct 24, 2008, 3:26:09 PM10/24/08
to
On Oct 24, 1:37 am, Pallav singh <singh.pal...@gmail.com> wrote:

> pthread_mutex_lock(&pq->mutexvar);
> cout << "before wait" << endl;
> pthread_cond_wait(&pq->condvar, &pq->mutexvar);
> cout << "after wait" << endl;

Suppose you share a car with your sister. One day, you want to use the
car. So you wait for your sister to get home. You wait, and wait, and
wait. She never comes home, and you never get to use the car. The car
is in the driveway and your sister is in bed.

Before you wait for something, you need to make sure it's sensible to
wait for it!

So check to make sure the car isn't in the driveway before you wait
for your sister to come home.

The 'pthread_cond_wait' function, despite its name, is not a
conditional wait. It's an unconditional wait *for* a condition.

DS

Dave Butenhof

unread,
Oct 27, 2008, 8:03:56 AM10/27/08
to
Szabolcs Ferenczi wrote:
> On Oct 24, 10:37 am, Pallav singh <singh.pal...@gmail.com> wrote:
>> Hi
>>
> At the user level you want to communicate an event from one thread to
> the other, don't you? The semaphore is a perfect software tool for
> this. You can replace your mutex-condition variable pair with a
> semaphore and then you can keep the waiting and signalling like you
> use it now.
>
> The other option is that you must introduce an additional shared
> variable, a flag, and set-check that flag. Then you must protect the
> shared flag with a mutex and you can optimise the waiting with the
> condition variable as indicated for you here:

In this case Szabolcs' routine blindly obsessive "use a semaphore"
mantra may accidentally be almost half right. At least, it provoked me
to look at the rest of your code a little more closely than I (or
apparently he) had previously.

(Of course, the code you posted may have little to do with your real
code or your algorithmic intent, but it's all we have to work from. If
any specific suggestions here aren't relevant for your actual intent,
that's fine; take them as generic hints.)

First, there appears to be no real application shared data that serves
obviously as a proper predicate, and my previous hurried answer focused
too narrowly on repairing the incorrect predicate management around your
condition variable -- I failed to observe that you didn't actually have
a predicate.

To that limited extent, Szablocs is correct; you wouldn't need to invent
a shared data predicate, if you use a semaphore which includes its own
predicate. (System V and POSIX semaphores use counters; BSD semaphores
are boolean.) Semaphores also avoid the "missed wakeup" issue to which
David Schwartz refers, because they have a "memory".

To expand on David's example about your sister and the car, a semaphore
would remember that your sister had previously left the car in the
driveway, so you wouldn't need to remember to check before waiting. One
way to think of this is that you share a set of car keys, and "signal"
that the car is available by hanging them in the hallway. So you check
whether keys are present; if so, the car is available and, if not, the
car is presumed to be out.

But in the name of making a predicate that may be more convenient to
check, you've also added a level of indirection. Your sister might have
come home tired and left the keys in her purse when she went to sleep.
You'll never know because you're relying on the car keys instead of
looking at the driveway. You've really added a NEW predicate, that's
separate from the REAL predicate about which you care, and which needs
to be managed separately. Its better to have a predicate that's
naturally and closely related to the real condition you care about; the
more indirect, the more complication and the greater the chance of error.

If there IS no other natural predicate, you might be better off creating
a semaphore (which bundles a predicate with the synchronization and wait
mechanism) than to invent a mutex, condition variable, and a boolean
predicate that serves no other purpose. (Then again, if you don't
already have a natural predicate you need to give some serious thought
to why you're waiting in the first place; there's got to be a reason why
you're waiting, and a condition under which you stop waiting; and that's
your predicate. In many cases you simply don't need to invent another
predicate and signaling mechanism on top of that, if you find the right
way to think about it!)

In this case, you seem to be almost using the message queue instead of a
semaphore; adding either semaphore or condition variable on top of this
should (or at least could) be redundant. But... "almost" is the key
phrase here, because you've made things harder for yourself, and there's
another layer of the onion to pull back.

You're accepting socket connections, reading the input data, and
parceling it out to child threads. Except while each child sends data to
its own external socket, you're using a single global message queue for
the master to tell each child what data to send; and the master has
already waited to read the input data for each connection. That is,
although you technically have independent threads, each with its own
outgoing socket, capable of all writing data simultaneously, you're
forcing them to operate (mostly) serialized by copying all the data from
the master to a child through a single message queue shared by all
children. You can really only receive and send one message at a time,
and the only reason to have multiple children here is that each
essentially is statically bound to a single outgoing socket.

That's enormously inefficient! It's possible (though by no means
guaranteed) that the message queue may be more efficient than sending
through the external socket; however there's really little value here
over simply having the master send each socket message directly. (And
adding the extra data copying and context switches, this may well be worse.)

In general, "thread per connection" is a bad model for threading
servers; you add a lot of context switches for a fairly small (best
case) simplification in coding model.

You'd probably be much better off, in your current model, having each
child serve a particular connection; both input and output sockets.
(It's statically bound to a particular connection anyway through the
output socket FD at creation.) Why not simply block waiting for input,
read the input, and send it to the output? That way each child would be
independent, with its own predicate (its private input socket) that
really IS what it wants to know rather than some invented and redundant
signaling mechanism.

In a more efficient "pooled" server, each child might be dynamically
bound to an active connection, when the master detects activity through
its select(). A child would be designated to service that connection
until it goes idle, and then wait for another connection to become
active. The master would no longer be a bottleneck as it would only be
managing the pool of connections rather than serving as a critical path
(reading the input socket, echoing the data through the message queue)
for each transaction.

Markus Elfring

unread,
Oct 27, 2008, 8:52:27 AM10/27/08
to
> unsigned long Thread_id = pthread_self();

I recommend also to look for a correct handling of thread identifiers. There is
no easy conversion for the data type "pthread_t" in some software environments.
http://groups.google.de/group/comp.unix.programmer/msg/21fa93fa89620648
http://groups.google.de/group/comp.programming.threads/msg/b28dac07fd7ca453

Regards,
Markus

Chris M. Thomasson

unread,
Oct 28, 2008, 12:20:12 AM10/28/08
to

"Dave Butenhof" <david.b...@hp.com> wrote in message
news:ge4anc$v9q$1...@usenet01.boi.hp.com...

> Szabolcs Ferenczi wrote:
>> On Oct 24, 10:37 am, Pallav singh <singh.pal...@gmail.com> wrote:
>>> Hi
>>>
>> At the user level you want to communicate an event from one thread to
>> the other, don't you? The semaphore is a perfect software tool for
>> this. You can replace your mutex-condition variable pair with a
>> semaphore and then you can keep the waiting and signalling like you
>> use it now.
>>
>> The other option is that you must introduce an additional shared
>> variable, a flag, and set-check that flag. Then you must protect the
>> shared flag with a mutex and you can optimise the waiting with the
>> condition variable as indicated for you here:
>
> In this case Szabolcs' routine blindly obsessive "use a semaphore" mantra
> may accidentally
^^^^^^^^^^^^^^^

> be almost half right. At least, it provoked me to look at the rest of your
> code a little more closely than I (or apparently he) had previously.

[...]

I really like using condvars when the predicate is a __natural__ part of a
given shared data-structure __as-is__. Think of collections which expose
boundary conditions as a part of their inherent behavior; generic collection
is full or empty, well, the collection __itself__ can communicate that
condition such that it can be used directly __within_the_predicate__ of a
condvar. In this case, semaphores simply contain _redundant_ state.

In cases where the condition state has no bearing, or is not
directly/indirectly provided, by the application infrastructure and/or
data-structures contained therein, and thus _needs_ to be artificially
created, well, a semaphore just very well may be the best option indeed. In
this case, I think that Szabolcs is absolutely correct!

I don't think that Szabolcs stupid; He just sure seems to sometimes act that
way when he trolls! He know how to get my goat to kick the damn gate down
and run wild... Usually run into a freeway loaded with traffic...

:^/

Szabolcs Ferenczi

unread,
Oct 28, 2008, 6:52:18 PM10/28/08
to
On Oct 27, 1:03 pm, Dave Butenhof <david.buten...@hp.com> wrote:
[...]

> In this case Szabolcs' routine blindly obsessive "use a semaphore"
> mantra may accidentally be almost half right...

Although not "accidentally" and not "half right," thus, not "blindly
obsessive."---Whenever I suggest to use a semaphore instead of the flag
+mutex+condvar combination, it is always the simpler solution to the
problem that needs to be solved. It is because in all those cases the
user level problem to be solved is to signal a problem level event,
which is not mapped to the shared data space. Just have a look at some
examples from the past next to this one:

"Understanding pthread_cond_wait()"
http://groups.google.com/group/comp.programming.threads/msg/4a404e8ec93303d5

"Linux pthread_cond_broadcast waking only one thread out of four
waiting"
http://groups.google.com/group/comp.programming.threads/msg/a30496fcbeee19ac

"order of pthread_mutex_unlock()/pthread_cond_signal()"
- flag+mutex+condvar
http://groups.google.com/group/comp.programming.threads/msg/41fa64966fe090ca
- semaphore
http://groups.google.com/group/comp.programming.threads/msg/64cfa20ab92bcd12

Check them out.

You and your blind followers were routinely attack it all along.
However, this is a recurring problem for those who try to get their
way into concurrent programming.

It is a concurrent programming smell when one tries to use a condition


variable as if it were a semaphore.

These (i.e. the semaphore and flag+mutex+condvar) are alternative
software tools and it is difficult for the newcomer to select the
right tool for the given task. However, with your blind attacking
mantra, you do not make their job easier.

> To that limited extent, Szablocs is correct; you wouldn't need to invent
> a shared data predicate, if you use a semaphore which includes its own

> predicate...

Your blindly obsessive routine about "the predicate" mantra creates
some problems for the newcomers to the field of concurrent
programming. You are half right with it but you are quite misleading
for the newcomer. Now, this terminology is why you are unable to think
clearly about the condition variable. It is especially apparent, if we
take the nonsense phrase of yours: "shared data predicate".

Yes, it is a predicate from the formal logic point of view, a
predicate created from the expression formed on the shared data
structures. That is why you are half right about it. However, we are
not in the formal logic domain but rather we are in the concurrent
programming domain.

We are talking about concurrent programs, i.e. concurrent threads of
computations, and here we formulate a __condition__ on the shared
variable space, a condition __when__ the thread of computation can
proceed. That is why you named the software tool the "condition
variable" and not the "predicate variable".

To be exact, you have taken the name over from the simplified monitor
concept (Mesa) and that is why you have taken over the naming too.
http://www.cs.berkeley.edu/~brewer/cs262/Mesa.pdf

It is named condition variable in concurrent programming but, on the
other side, the expression created on the shared variables is also
called the condition. It is the condition when the thread of
computation is allowed to proceed. If the condition is not met,
however, the thread of computation must be delayed. How do you delay
it? Well, you can hang the computation process until the condition is
fulfilled. When the condition is fulfilled, you send a wakeup signal.
Hence the special variable named condition variable. It is true in the
original monitor concept only!
ftp://reports.stanford.edu/pub/cstr/reports/cs/tr/73/401/CS-TR-73-401.pdf

Another solution is to keep checking the condition until it becomes
true. (See also the concept of the Conditional Critical Region).
"C. A. R. Hoare, Towards a Theory of Parallel Programming (1971)"

If all of your thread is carried out by a separate physical processor,
you can keep busy waiting. However, this is not the case with the
practical computers, so the busy wait can be made economic with
respect to the resource usage. The resource here is the computing
power. So we use the so called condition variable, not any predicate
variable, however, and the thread of computation is hanging on the
condition variable awaiting a signal when it is economic to re-
evaluate the condition on the shared variables. This is the Mesa way
and they started to mix-in the phrase predicate. That is what mislead
you.
http://www.cs.berkeley.edu/~brewer/cs262/Mesa.pdf

I hope I could help you to understand why you should not use the
phrase "shared data predicate" and why you should refrain yourself
attacking others with low language whenever you see the phrase
"semaphore".

If you need any further help, just ask.

Best Regards,
Szabolcs

David Schwartz

unread,
Oct 28, 2008, 8:06:27 PM10/28/08
to
Szabolcs Ferenczi wrote:

This is comedy gold. Thank you for brightening my day.

DS

Szabolcs Ferenczi

unread,
Oct 29, 2008, 2:58:29 AM10/29/08
to

Well, it was not for you, was it?

You may try to follow it, although, you are hopeless, you cannot be
helped, I am afraid. You just jump as a monkey again, as usual.
Instead, you might try to understand the reasoning, though.

Best Regards,
Szabolcs

David Schwartz

unread,
Oct 29, 2008, 5:04:04 PM10/29/08
to
On Oct 28, 11:58 pm, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:

> You may try to follow it, although, you are hopeless, you cannot be
> helped, I am afraid. You just jump as a monkey again, as usual.
> Instead, you might try to understand the reasoning, though.

I tried, but the soda coming out of my nose was too much of a
distraction.

DS

Szabolcs Ferenczi

unread,
Oct 29, 2008, 5:28:00 PM10/29/08
to

That is your problem, jumping monkey.

Best Regards,
Szabolcs

Dave Butenhof

unread,
Oct 29, 2008, 6:41:07 PM10/29/08
to
Chris M. Thomasson wrote:
>
> I don't think that Szabolcs stupid; He just sure seems to sometimes act
> that way when he trolls!

You know, Chris, that's very generous of you. Every once in a while I
almost agree...

And then he posts another reply, and I'm not so sure anyone could do
quite so thorough and consistent a job of only pretending to be an
obnoxious jerk. Then again, perhaps I'm not giving him enough credit for
acting talent.

And he can't seem to say anything at all without blatantly irrelevant
personal attacks on anyone and everyone who disagrees with him, which
makes him extraordinarily unpleasant even when he does occasionally say
something that's at least technically worthwhile.

rani_s...@hotmail.com

unread,
Oct 30, 2008, 12:38:33 AM10/30/08
to
> Best Regards,
> Szabolcs

I'm silently following this rivalry for a while and since I think that
you have good intentions, it seems unnecessary and actually armful for
the readers you want to assist. I think that some insignificant
disagreements went out of control and into bad dynamics when we should
all be at peace in this context of friendly debates.

I feel that I can speak of behalf of most of the readers in this
newsgroup that we are blessed with having Dave Butenhof regularly
posting. His insights and observations are simply priceless. Though I
hold great respect for the researchers that invented some of the
concepts that we debate about, when it comes to practical multi-
threaded programming, experts like Dave are the authority with years
of experience and influence.

Like me, you seem to be very opinionated and loyal to your beliefs,
but by being open minded for experts like Dave you actually have
opportunity to refine your believes and that will serve you well
growing as an expert.

For example, As a Microsoft employee I work solely in corners of
windows in which conditional variables were never heard of but still I
learn a lot from Dave's posts (and book) about multi-threaded
programming when he talks about conditional variables. I often see how
lack of such fundamental construct resulted with over complicated
solutions that are hard to reason about.

Please let's try to be more cooperative in our common quest to help
others.

Rani

David Schwartz

unread,
Oct 30, 2008, 6:23:52 AM10/30/08
to
On Oct 29, 9:38 pm, rani_shar...@hotmail.com wrote:

> Please let's try to be more cooperative in our common quest to help
> others.
>
> Rani

It may seem like this is just a misunderstanding or some kind of
rivalry blown out of proportion. But if you look at the history, I
think you will come the conclusion that S.F. has a strange agenda that
isn't in any way about helping others.

We all gave him the benefit of the doubt for a long time. He has used
up any such conceivable benefit.

DS

Szabolcs Ferenczi

unread,
Oct 30, 2008, 7:03:56 AM10/30/08
to
On Oct 30, 5:38 am, rani_shar...@hotmail.com wrote:

> [...]


> For example, As a Microsoft employee I work solely in corners of
> windows in which conditional variables were never heard of but still I
> learn a lot from Dave's posts (and book) about multi-threaded
> programming when he talks about conditional variables. I often see how
> lack of such fundamental construct resulted with over complicated
> solutions that are hard to reason about.
>
> Please let's try to be more cooperative in our common quest to help
> others.

Well, I challenge you to find instances where I did not help the
original poster in comp.programming.threads whenever I have joined to
a discussion thread. There might be one or two exceptions but most of
the time I join to offer help. Check out my first postings to
discussion threads. I hope you will not escape from this challenge.

Besides, the part that you have generously omitted from the post you
were reacting on enumerated some cases where I definitely helped the
OP with alternative solutions to his problem.

<quote>
"Understanding pthread_cond_wait()"
http://groups.google.com/group/comp.programming.threads/msg/4a404e8ec93303d5

"Linux pthread_cond_broadcast waking only one thread out of four
waiting"
http://groups.google.com/group/comp.programming.threads/msg/a30496fcbeee19ac

Check them out.
</quote>

What reactions can you see on those discussion threads from Dave,
David and Christ? Well, you can see a blind and unconditional attack
whenever they see the word `semaphore'. Why? We have a variety of
programming tools around. If a semaphore is the simplest solution for
a synchronisatinon problem, why should not it be favoured instead of
the more complicated and consequently more error prone synchronisation
solution (shared flag+mutex+condvar)?

Now, I challenge you to find instances when I did not help people in
this forum apart from struggling with the nasty reactions of this
hybrisful triumvirate? Check out my first postings to discussion
threads.

Why do you find semaphores equal to evil? What is your problem with
solution to synchronisation problems with semaphores when it gives a
simple solution to the problem? Why do you favour the more complicated
and more prone to error synchronisation constructions when there is a
simpler one around?

What problems can you find in suggesting alternative solutions for the
problems of people? Please ask the help of your colleagues and
together in a team work try to find anything definitely wrong in my
suggestions to the problems of the OPs.

What problems do you have in learning about the details of when and,
first of all, for what reason a specific synchronisation programming
tool has been invented?

After seeing so many misuse of condition variables, I even helped
others offering a simple check on the usage of the condition
variables.
http://groups.google.com/group/comp.programming.threads/browse_frm/thread/0ff7ac10adadee22
Why does the condition variable test hurts you guys? Isn't it simple
and harmless? Doesn't it help you to use it in a correct way? It could
have been helped to the OP here too.

Please check around at Microsoft among your colleagues who are more
familiar with concurrent programming and with condition variables and
ask their advise. Try to check it from first hand source and try to
contact Tony Hoare. Is he still with Microsoft?

I hope I could help you too, though, especially if you try to honestly
answer the questions. If you cannot manage with it, ask the help of
others in your environment to find the answers.

Best Regards,
Szabolcs

David Schwartz

unread,
Oct 30, 2008, 9:03:35 AM10/30/08
to
On Oct 30, 4:03 am, Szabolcs Ferenczi <szabolcs.feren...@gmail.com>
wrote:

> Well, I challenge you to find instances where I did not help the
> original poster in comp.programming.threads whenever I have joined to
> a discussion thread. There might be one or two exceptions but most of
> the time I join to offer help. Check out my first postings to
> discussion threads. I hope you will not escape from this challenge.

On the contrary, you consistently maliciously mislead the original
posters in an attempt to mislead them all in precisely the same
direction.

For example, look at:
<ebdf4ebd-8d63-4a71...@f63g2000hsf.googlegroups.com>
where you said:
"You should consider using simple semaphores for event signaling
(which is your problem to solve) instead of the more complicated
mutex---condition variable pairs which are not designed for this
task."
In fact, the OP was using mutex/cv pairs for precisely their designed
task.

I cite many, many examples where you tell innocent posters that
condition variables cannot or should not be used for event signaling.
In fact, this is precisely what they are for.

"That is a typical misuse of the condition variable. You can use the
condition variable in an auxiliary manner, i.e. for optimisation for
the problem-level busy waiting loop. That means you do not call signal
on a condition variable to send a problem level signal."

"My statement was about the fact that for event signaling you can only
use
semaphore but you cannot use condition variable..."

These were all responses to innocent unsophisticated posters who had
no idea they were getting a bizarre viewpoint not shared by anybody
else on the planet. He created a serious possibility that those
posters would be completely mislead.

He has no interest in helping people, he merely uses them to goad
people into feeling obligated to prevent them from being harmed. He's
like the villain who can't defeat Superman directly, so he sets a few
houses on fire to keep the hero busy while he robs the bank.

DS

Szabolcs Ferenczi

unread,
Oct 30, 2008, 2:30:21 PM10/30/08
to
On Oct 30, 2:03 pm, David Schwartz <dav...@webmaster.com> wrote:

> [...]
> For example, look at:
> <ebdf4ebd-8d63-4a71-82e4-3f54ee617...@f63g2000hsf.googlegroups.com>


> where you said:
> "You should consider using simple semaphores for event signaling
> (which is your problem to solve) instead of the more complicated
> mutex---condition variable pairs which are not designed for this
> task."
> In fact, the OP was using mutex/cv pairs for precisely their designed
> task.

Negative. Just the opposite.

We are talking about this discussion thread:

"Linux pthread_cond_broadcast waking only one thread out of four
waiting"

http://groups.google.com/group/comp.programming.threads/browse_frm/thread/c8afba309d9528ce

There, the OP had the problem that he wanted to give a signal from a
master thread of computation to the workers when their work package
was ready.

Contrary to what you think, the OP mis-used the condition variable
there since the usage pattern of the condition variable was just like
if it were a semaphore:

void *forward_h_worker(void *in)
{
...
pthread_mutex_lock(&forward_h_lock[group]);

for (;;) {
pthread_cond_wait(&forward_h_cond_worker,
&forward_h_lock[group]);
// do work
...
void forward_h_manager(float *inputs, float *outputs, h_weights_t
*h_weights)
{
pthread_mutex_lock(&forward_h_lock_counter);
// prepare work package
pthread_cond_broadcast(&forward_h_cond_worker);
...

"Anyone else on the planet" but you, so anyone who has just a basic
education in concurrent programming immediately sees that this usage
pattern could work with semaphores but this is not the usage pattern
how you, sorry not you but any educated person in concurrency, uses
the condition variable.

Hence, I have given the OP a detailed help in this post:
http://groups.google.com/group/comp.programming.threads/msg/a30496fcbeee19ac
where I explained the solution to his problem BOTH with shared flag
+mutex+condvar AND with semaphore.

What is wrong with it?

As a bonus, I have also demonstrated that the condition variable is
only a performance optimisation means not contributing to the
functional behaviour and it is not any synchronisation means on its
own right. Consequently it cannot be used on its own, i.e. without any
shared variables but a semaphore can be used in that case.

Of course you and your friends here are unable of thinking
sophisticated and you can only stick to the condition variable,
however, any disciplined people can solve a problem in various ways,
you know.

Best Regards,
Szabolcs

Chris M. Thomasson

unread,
Oct 30, 2008, 4:55:19 PM10/30/08
to

"Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
news:0ff273ae-cbed-4098...@u28g2000hsc.googlegroups.com...

On Oct 30, 2:03 pm, David Schwartz <dav...@webmaster.com> wrote:

> > [...]
> > For example, look at:
> > <ebdf4ebd-8d63-4a71-82e4-3f54ee617...@f63g2000hsf.googlegroups.com>
> > where you said:
> > "You should consider using simple semaphores for event signaling
> > (which is your problem to solve) instead of the more complicated
> > mutex---condition variable pairs which are not designed for this
> > task."
> > In fact, the OP was using mutex/cv pairs for precisely their designed
> > task.

> Negative. Just the opposite.

> We are talking about this discussion thread:

> "Linux pthread_cond_broadcast waking only one thread out of four
> waiting"
> http://groups.google.com/group/comp.programming.threads/browse_frm/thread/c8afba309d9528ce

> There, the OP had the problem that he wanted to give a signal from a
> master thread of computation to the workers when their work package
> was ready.

> Contrary to what you think, the OP mis-used the condition variable
> there since the usage pattern of the condition variable was just like
> if it were a semaphore:

[...]

> "Anyone else on the planet" but you, so anyone who has just a basic
> education in concurrent programming immediately sees that this usage
> pattern could work with semaphores but this is not the usage pattern
> how you, sorry not you but any educated person in concurrency, uses
> the condition variable.

> Hence, I have given the OP a detailed help in this post:
> http://groups.google.com/group/comp.programming.threads/msg/a30496fcbeee19ac
> where I explained the solution to his problem BOTH with shared flag
> +mutex+condvar AND with semaphore.

> What is wrong with it?

You forgot to explain to the OP that `sem_wait()' can indeed be interrupted
by a signal and return `EINTR'.


> As a bonus, I have also demonstrated that the condition variable is
> only a performance optimisation means not contributing to the
> functional behaviour and it is not any synchronisation means on its
> own right. Consequently it cannot be used on its own, i.e. without any
> shared variables but a semaphore can be used in that case.

> Of course you and your friends here are unable of thinking
> sophisticated and you can only stick to the condition variable,
> however, any disciplined people can solve a problem in various ways,
> you know.

I explain to you that a semaphore cannot do what a condvar does:

http://groups.google.com/group/comp.programming.threads/msg/6dfc7ba60ffbbb03

The condvar is a richer synchronization primitive than a single semaphore
alone. For instance, how you broadcast a semaphore and honor proper wake
generations?

Szabolcs Ferenczi

unread,
Oct 30, 2008, 4:56:49 PM10/30/08
to
On Oct 30, 2:03 pm, David Schwartz <dav...@webmaster.com> wrote:

[you quote from me:]


> "My statement was about the fact that for event signaling you can only
> use
> semaphore but you cannot use condition variable..."

And I continued the sentence, which you have omitted for some unknown
reason:

"... as it appeared to the example attached earlier in this thread."

http://groups.google.com/group/comp.programming.threads/msg/fd793c92f00cb826

How did it appear there? I mean the usage of the condition variable:

<quote from="
http://groups.google.com/group/comp.programming.threads/msg/fc06ff81b98a9823
">
void
dosignal (void)
{
pthread_mutex_lock (&cond_mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock (&cond_mutex);
/* sched_yield(); without this I get 0! with Linux and RT patches
*/
}
</quote>

So the OP uses the condition variable again as if it were a semaphore.
He wants to signal an event and he uses a bare condition variable for
it. No shared flag nor any other shared variable but rather just the
bare condition variable.

With a bare semaphore, it would work this way. This is the usage
pattern of the semaphore if you use the semaphore for signalling an
event (problem level event!).

So let us be exact here: We are talking about the problem-level event
signalling, which is the problem of this OP as well.

> These were all responses to innocent unsophisticated posters who had
> no idea they were getting a bizarre viewpoint not shared by anybody

> else on the planet. [...]

Oh yes, this view is shared by many others too. Obviously. Even your
authority, Dave Butenhof does share this viewpoint when he has a clean
moment and he manages to suppress his conditioned reflexes.

<quote from="
http://groups.google.com/group/comp.programming.threads/msg/b21dd065ee5f4414


">
On Oct 27, 1:03 pm, Dave Butenhof <david.buten...@hp.com> wrote:
> To that limited extent, Szablocs is correct; you wouldn't need to invent
> a shared data predicate, if you use a semaphore which includes its own

> predicate. (System V and POSIX semaphores use counters; BSD semaphores
> are boolean.) Semaphores also avoid the "missed wakeup" issue to which
> David Schwartz refers, because they have a "memory".

</quote>

Note that here the "limited context" is exactly the signalling of a
problem-level event from one thread of computation to the other. That
is what I am talking about all along and that is what some hybrisful
ones like you will never understand.

Now, Chris obviously runs behind Dave like a little pet and he shares
the master's view. Consequently, when the master has some clean moment
so does Chris. Besides, he is so eager in catching me that I could
have a chance to coach him to come up with the excellent active object
solution in C++ and now anyone can use it. So we do help others here.
See the discussion thread:

"What's the connection between objects and threads?"
http://groups.google.com/group/comp.lang.c++/browse_frm/thread/f7cae1851bb5f215

Well, it was not easy to coach him. You can see it if you try to
follow that discussion thread since old believes are hard to break.
There were a lot of self nominated "authorities" there too who
believed that it cannot work. You can see again that "anybody else on
the planet" believed that it is not possible to merge the object with
the thread into an active object in C++. It turned out that it is
possible and it results in some higher level programming construction.

Well, there was a time when "anybody else on the planet" believed that
the Earth was the center of the Universe. Guys like you have even
committed crimes because you are so aggressive and you believe that
anyone who thinks differently must be eliminated.

But, my friend, the world is progressing and creatures like you will
be just left behind. That is how it works.

Sorry for the bad news, buddy.

Best Regards,
Szabolcs

Chris M. Thomasson

unread,
Oct 30, 2008, 5:44:22 PM10/30/08
to

"Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
news:7e9409ce-ddd7-48d7...@m3g2000hsc.googlegroups.com...
[...]

> Now, Chris obviously runs behind Dave like a little pet and he shares
> the master's view. Consequently, when the master has some clean moment
> so does Chris.

Oh come on!


> Besides, he is so eager in catching me that I could
> have a chance to coach him to come up with the excellent active object
> solution in C++ and now anyone can use it. So we do help others here.
> See the discussion thread:

> "What's the connection between objects and threads?"
> http://groups.google.com/group/comp.lang.c++/browse_frm/thread/f7cae1851bb5f215

> Well, it was not easy to coach him. You can see it if you try to
> follow that discussion thread since old believes are hard to break.
> There were a lot of self nominated "authorities" there too who
> believed that it cannot work. You can see again that "anybody else on
> the planet" believed that it is not possible to merge the object with
> the thread into an active object in C++. It turned out that it is
> possible and it results in some higher level programming construction.

I created the `active' helper template in order to get around the fact that
one cannot start threads from the ctor of a thread base-class. I will create
a race-condition in which the derived class could be invoked before its ctor
is completed. Bad stuff! Anyway, as for `active' object itself, I have
created a new post which shows one of its possible uses:

http://groups.google.com/group/comp.programming.threads/browse_frm/thread/44190e3b9ac81a69

AFAICT, its really convenient when applied to automatic running and joining
any object which exposes a common interface (T::active_run/join). So far, I
like it better than the Boost method of creating threads...


[...]

Chris M. Thomasson

unread,
Oct 30, 2008, 5:51:08 PM10/30/08
to

"Chris M. Thomasson" <n...@spam.invalid> wrote in message
news:fNpOk.16$kd...@newsfe01.iad...

>
> "Szabolcs Ferenczi" <szabolcs...@gmail.com> wrote in message
> news:7e9409ce-ddd7-48d7...@m3g2000hsc.googlegroups.com...
> [...]
>
>> Now, Chris obviously runs behind Dave like a little pet and he shares
>> the master's view. Consequently, when the master has some clean moment
>> so does Chris.
>
> Oh come on!
>
>
>
>
>> Besides, he is so eager in catching me that I could
>> have a chance to coach him to come up with the excellent active object
>> solution in C++ and now anyone can use it. So we do help others here.
>> See the discussion thread:
>
>> "What's the connection between objects and threads?"
>> http://groups.google.com/group/comp.lang.c++/browse_frm/thread/f7cae1851bb5f215
>
>> Well, it was not easy to coach him. You can see it if you try to
>> follow that discussion thread since old believes are hard to break.
>> There were a lot of self nominated "authorities" there too who
>> believed that it cannot work. You can see again that "anybody else on
>> the planet" believed that it is not possible to merge the object with
>> the thread into an active object in C++. It turned out that it is
>> possible and it results in some higher level programming construction.
>
> I created the `active' helper template in order to get around the fact
> that one cannot start threads from the ctor of a thread base-class. I will
> create a race-condition in which the derived class could be invoked before
> its ctor is completed.

Here is a simple example:
____________________________________________________________________
#include <cstdio>
#include <cstdlib>

static void call_abstract_virtual_indirect(class base*);


class base {
friend void call_abstract_virtual_indirect(class base*);
virtual void on_action() = 0;


public:
base() {
call_abstract_virtual_indirect(this);
}


virtual ~base() throw() = 0;

};


base::~base() throw() {}

void call_abstract_virtual_indirect(base* _this) {
_this->on_action();

}


class derived : public base {
int const m_ctor;

public:
derived() : m_ctor(123456789) {


}


private:
void on_action() {
std::printf("(%p)::derived::on_action()\n", (void*)this);
if (m_ctor != 123456789) {
std::printf("(%p)::derived::on_action() - NOT CONSTRUCTED!\n",
(void*)this);
std::getchar();
std::abort();
}
}

};


int main() {
{
derived d;
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
std::puts("\n\n____________________________________________\n\
Press <ENTER> to exit...");
std::getchar();
return 0;

}
____________________________________________________________________


This will either default right off the bat, or it will output something with
"NOT CONSTRUCTED!" in it. The OP in the thread you refer to was trying to
create threads in the ctor of his thread base-class. Well, that has a
race-condition which can trigger the scenario demonstrated by the example
code above. You explicitly said in that thread that one can create threads
in a ctor. Well, this is misleading because its not always true. So, I
created the `active' helper template to show one case in which is it indeed
safe to create threads in a ctor. So be it...

rani_s...@hotmail.com

unread,
Oct 30, 2008, 11:43:14 PM10/30/08
to
> Best Regards,
> Szabolcs

I didn't try to an express any option about Semaphore vs. CV (I'm fine
with both) as I just wanted to give an example about being open
minded.

I still believe that you have good intention and abilities in helping
others but with the current state of the discussions it will be hard
for you to reach your goal.

Can you at least avoid responding to any personal attacks in order to
bring the flames down while still perusing your good intentions?

Rani

0 new messages