1) The = operator on a string copies by value. The following code is copying by value into the 'buffer' variable. However, later you are using p1_string in an infinite loop expecting it to update. Assigning a new value to the pthread_param.buffer does not change the value of px_string. Thus, in this case the strings will always equal their initial value and string 1 will always be less than string 2.
pt1_param.buffer = p1_string; //assignment by value
pt2_param.buffer = p2_string; //assignment by value
2) Consider the following race condition in the code. The getline() function in the producer and the if/cout code could both be accessing the buffer variable at the same time. Rearranging the order of (pseudo)code in the producer to the following may appear to be very similar, however, it does changes the behavior quite a bit:
while (1)
{
sem_wait()
if (!getline(buffer))
break;
sem_post()
}
Now the producers have to immediately block and wait until they get a signal from the consumer that it's done accessing the buffer variables. It's calling the wait() before the post and this has a very significant effect that I will try to describe. Previously both the producers and consumer call sem_post before sem_wait and the respective semaphore counts are both incremented. Thus, when the producer tries to wait() it just ends up decrementing the already existing count and it continues on. The same thing happens in the producer as a result of the consumer having incremented its semaphore already. Thus every iteration of the loop in both the producer and the consumer becomes an unpredictable race situation to use the buffer variable(s).