i am trying to use pthread clean up function to release the mutex which the cancelled thread is holding
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#define SHOW_TECH_CMD_MAX_EXEC_TIME 5 //in secs
pthread_mutex_t waitMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t testMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t waitCond = PTHREAD_COND_INITIALIZER;
void mutex_cleanup_handler(void *arg )
{
printf("cleanup \n");
pthread_mutex_unlock( &testMutex );
}
void *execute_on_thread(void *arg);
void *execute_on_thread(void *arg)
{
pthread_cleanup_push(mutex_cleanup_handler, NULL);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_mutex_lock( &testMutex );
while(1)
{
printf(".");
}
pthread_mutex_lock( &waitMutex );
pthread_cond_signal( &waitCond );
pthread_mutex_unlock( &waitMutex );
pthread_cleanup_pop(1); // even with 1 behavior remains the same
return (void *) 0;
}
int main( )
{
pthread_t tid;
struct timespec ts;
int error;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 5;
pthread_create(&tid,NULL,execute_on_thread,NULL);
pthread_mutex_lock(&waitMutex);
error = pthread_cond_timedwait(&waitCond, &waitMutex,&ts);
pthread_mutex_unlock(&waitMutex);
printf("come here 1\n");
if(error == ETIMEDOUT)
{
printf("come here 2\n");
error = pthread_cancel(tid);
if(error != 0)
{
printf("come here 3\n");
}
}
}
cleanup function is not getting called itself
the thread is getting cleared properly , but the cleanup function is not being called
As Man says:
The pthread_cleanup_pop() function removes the routine at the top of
the stack of clean-up handlers, and optionally executes it if execute
is nonzero.
Then you have to write:
pthread_cleanup_pop(1);
Take note that your thread function definition is incorrect
EDIT
Using your code, the correction below works.
if(error == ETIMEDOUT)
{
printf("come here 2\n");
error = pthread_cancel(tid);
pthread_join(tid, NULL);
if(error != 0)
{
printf("come here 3\n");
}
You must wait the thread completion before end of your application.
In your code, after thread cancel request, the application ends immediately.
Related
Program description:
I wrote a demo for conditional waiting. The program starts two threads and then waits for both to finish. One of the threads reads user-pressed keys from the keyboard, and if the q key is pressed, sets a condition variable, after that the thread ends.
How can I implement the second thread to run in an infinite loop a sequence in which it waits for the condition variable for up to 1 second, and if the set variable appears then it exits the infinite loop, and if it does not appear and expires in 1 second, it displays a * on the console and returns to standby?
#include<pthread.h>
#include<stdio.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
pthread_mutex_t m=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t c=PTHREAD_COND_INITIALIZER;
void *fun1()
{
pthread_mutex_lock(&m);
while (1)
{
char ch;
scanf("%c",&ch);
if(ch=='q')
{
pthread_mutex_unlock(&m);
pthread_cond_signal(&c);
pthread_exit(NULL);
}
}
}
void *fun2()
{
struct timespec to;
pthread_condattr_t attr;
pthread_condattr_init( &attr);
pthread_condattr_setclock( &attr, CLOCK_MONOTONIC);
pthread_cond_init( &c, &attr);
clock_gettime(CLOCK_MONOTONIC, &to);
to.tv_sec += 1;
while (1)
{
printf("hello world\n");
int rc=pthread_cond_timedwait(&c,&m,&to);
printf("%d",rc==ETIMEDOUT);
pthread_exit(NULL);
// if(rc==ETIMEDOUT)
// {
// }
// pthread_exit(NULL);
}
}
int main()
{
pthread_t id[2];
pthread_mutex_init(&m,NULL);
pthread_cond_init( &c, NULL);
pthread_mutex_lock(&m);
pthread_create(&id[0],NULL,fun1,NULL);
pthread_create(&id[1],NULL,fun2,NULL);
pthread_join(id[0],NULL);
pthread_join(id[1],NULL);
pthread_mutex_destroy(&m);
return 0;
}
The structure of the code looks at-best to be pure-guesswork. Pthread mutex and condition variable pairing has specific rolls and responsibilities.
The mutex protects some external 'predicate' data
The condition variable signals a change to 'predicate' data.
The management of both the mutex and the condition variable is completely wrong.
repeated initialization of the already-initialized objects.
acquiring, and never releasing the mutex in fun1
both functions have the wrong signature for proper pthread threads.
neither function provides state return values
Related, some pthread implementations do not support clock-selection. In those cases, even fixing the code, the condition variable cannot be configured for monotonic clock selection; realtime is the only alternative.
Fixing everything above,
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t c = PTHREAD_COND_INITIALIZER;
bool quit = false;
void *fun1(void *pv)
{
while (1)
{
char ch;
scanf("%c", &ch);
if (ch == 'q')
{
// latch mutex before changing predicate
pthread_mutex_lock(&m);
quit = true;
pthread_cond_signal(&c);
pthread_mutex_unlock(&m);
break;
}
}
return pv;
}
void *fun2(void *pv)
{
pthread_mutex_lock(&m);
while (1)
{
printf("hello world\n");
struct timespec to;
clock_gettime(CLOCK_REALTIME, &to);
to.tv_sec += 1;
int rc = pthread_cond_timedwait(&c, &m, &to);
if (rc != ETIMEDOUT || quit == true)
break;
}
pthread_mutex_unlock(&m);
return pv;
}
int main()
{
pthread_t id[2];
pthread_create(id+0, NULL, fun1, NULL);
pthread_create(id+1, NULL, fun2, NULL);
pthread_join(id[0], NULL);
pthread_join(id[1], NULL);
return 0;
}
Pay close attention to how the mutex protects the predicate data (quit), and how that data is never checked, nor modified, without protection from that mutex by any thread. It's important.
Finally, note that fun1 (or fun2 ; pick one) is ultimately pointless in this code. Starting threads and waiting for them all to finish as the sole responsibility of main is a code smell that something can be done in main to avoid at least one of those threads. For example:
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t c = PTHREAD_COND_INITIALIZER;
bool quit = false;
void *fun2(void *pv)
{
pthread_mutex_lock(&m);
while (1)
{
printf("hello world\n");
struct timespec to;
clock_gettime(CLOCK_REALTIME, &to);
to.tv_sec += 1;
int rc = pthread_cond_timedwait(&c, &m, &to);
if (rc != ETIMEDOUT || quit == true)
break;
}
pthread_mutex_unlock(&m);
return pv;
}
int main()
{
pthread_t id;
pthread_create(&id, NULL, fun2, NULL);
while (1)
{
char ch;
scanf("%c", &ch);
if (ch == 'q')
{
// latch mutex before changing predicate
pthread_mutex_lock(&m);
quit = true;
pthread_cond_signal(&c);
pthread_mutex_unlock(&m);
break;
}
}
pthread_join(id, NULL);
return 0;
}
Does exactly the same thing as the previous code, but uses main as the driver for what fun1 was originally doing. Always consider this as an option worth pursuing if you can. Be kind to your scheduler; it will return the favor someday.
If I use the pthread_create() call in an infinite while loop in main, does it create multiple threads each time or will it only create the 2 threads that I need?
while(1){
pthread_create(&thread_1...);
pthread_create(&thread_2...);
}
it creates multiple threads each time.
you can use pthread_cancel to cancel any thread from the process.
Below is one of many ways to handle the termination of thread upon some event/timeout etc..
#include <stdio.h>
#include <signal.h> // for sigaction
#include <stdlib.h> // for exit and
#include <pthread.h> // for pthread
#include <string.h> // for memset
#define TIMEOUT 10
pthread_t tid1, tid2;
void* thread_function1(void *arg)
{
while(1)
{
printf(" thread_function1 invoked\n");
sleep(1); //avoid heavy prints
}
}
void* thread_function2(void *arg)
{
while(1)
{
printf(" thread_function2 invoked\n");
sleep(1); //avoid heavy prints
}
}
static void timer_handler(int sig, siginfo_t *siginfo, void *context)
{
printf("Inside handler function timeout happened \n");
if( sig == SIGALRM)
{
pthread_cancel(tid1);
pthread_cancel(tid2);
//exit(0); to exit from main
}
}
int main()
{
int count = 0;
void *status;
struct sigaction act;
memset (&act, '\0', sizeof(act));
sigemptyset(&act.sa_mask);
/* Use the sa_sigaction field because the handles has two additional parameters */
act.sa_sigaction = timer_handler;
/* The SA_SIGINFO flag tells sigaction() to use the sa_sigaction field, not sa_handler. */
act.sa_flags = SA_SIGINFO;
if (sigaction(SIGALRM, &act, NULL) < 0)
{
perror ("sigaction SIGALRM");
return 1;
}
alarm (TIMEOUT);
pthread_create(&tid1,NULL,thread_function1,NULL);
pthread_create(&tid2,NULL,thread_function2,NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
printf(" MIAN ENDS ...BYE BYE \n");
return 0;
}
I want to print for infinity the below message "What a wonderful world!" , I have from the begin the 3 threads to do this job the first one "What a , second one "Wonderful" and third one "world" , ( I am giving as parameter in ./a.out 3) , the problem in the below code is that the message displayed like this : What a wonderful what a wonderful the World is missing. I think Something is bad with the conditional variables, any suggestions?
int p;
void *disp(void *arg);
pthread_mutex_t muta,mutb,mutc;
pthread_cond_t condition_cond= PTHREAD_COND_INITIALIZER;
void *disp(void *arg)
{
int id=*(int*)arg;
free(arg);
arg=0;
pthread_mutex_lock(&muta);
while (id==0)
{
pthread_cond_wait (&condition_cond,&muta);
}
printf("What a");
pthread_mutex_unlock(&muta);
pthread_mutex_lock(&mutb);
while (id==1)
{
pthread_cond_wait (&condition_cond,&mutb);
}
printf(" Wonderful");
pthread_mutex_unlock(&mutb);
pthread_mutex_lock(&mutc);
while(id==2)
{
pthread_cond_wait (&condition_cond,&mutc);
}
printf(" World!\n");
pthread_mutex_unlock(&mutc);
return NULL;
}
EDIT: updated code based on the answer by dbush:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <semaphore.h>
#include <unistd.h>
int p;
void *disp(void *arg);
pthread_mutex_t mut=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond1= PTHREAD_COND_INITIALIZER;
pthread_cond_t cond2= PTHREAD_COND_INITIALIZER;
pthread_cond_t cond3= PTHREAD_COND_INITIALIZER;
void *disp(void *arg)
{
int id=*(int*)arg;
free(arg);
arg=0;
pthread_mutex_lock(&mut);
while(1)
{
if (id==0)
{
pthread_cond_wait (&cond1,&mut);
printf("What a ");
pthread_cond_signal (&cond2);
}
else if(id==1)
{
pthread_cond_wait (&cond2,&mut);
printf(" wonderful ");
pthread_cond_signal (&cond3);
}
else if(id==2)
{
pthread_cond_wait (&cond3,&mut);
printf(" world!\n ");
pthread_cond_signal (&cond1);
}
}
return NULL;
}
int main (int argc,char *argv[])
{
int i;
pthread_t *tid;
if(argc!=2)
{
printf("Provide number of threads.\n");
exit(1);
}
p=atoi(argv[1]);
tid=(pthread_t *) malloc (p*sizeof(pthread_t));
if (tid==NULL)
{
printf("Could not allocate memory.\n");
exit(1);
}
for (i=0;i<p;++i)
{
int *a;
a=malloc(sizeof(int)); //pointer to pass
*a=i;
pthread_create(&tid[i],NULL,disp,a);
}
pthread_cond_signal(&cond1);
for (i=0;i<p;++i)
pthread_join(tid[i],NULL);
return 0;
}
You've got your usage of mutexes and condition variables reversed. You need one mutex to control all three threads, and three condition variables (one for each thread).
After each thread finishes its work, it should signal the next thread using the condition variable for the target thread. Additionally, the main function needs to signal the first thread to get things started. You'll want it to sleep for a brief period so that all threads have time to start.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void *disp(void *arg);
pthread_mutex_t mux = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond1= PTHREAD_COND_INITIALIZER;
pthread_cond_t cond2= PTHREAD_COND_INITIALIZER;
pthread_cond_t cond3= PTHREAD_COND_INITIALIZER;
void *disp(void *arg)
{
int id=*(int*)arg;
free(arg);
arg=0;
pthread_mutex_lock(&mux);
while (1) {
if (id==0) {
pthread_cond_wait (&cond1,&mux);
printf("What a");
pthread_cond_signal(&cond2);
} else if (id == 1) {
pthread_cond_wait (&cond2,&mux);
printf(" Wonderful");
pthread_cond_signal(&cond3);
} else if (id == 2) {
pthread_cond_wait (&cond3,&mux);
printf(" World!\n");
pthread_cond_signal(&cond1);
}
}
return NULL;
}
int main()
{
pthread_t t1, t2, t3;
int *id = malloc(sizeof(int));
*id=0;
pthread_create(&t1, NULL, disp, id);
id = malloc(sizeof(int));
*id=1;
pthread_create(&t2, NULL, disp, id);
id = malloc(sizeof(int));
*id=2;
pthread_create(&t3, NULL, disp, id);
sleep(1);
pthread_cond_signal(&cond1);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
return 0;
}
I have 4 processed called A, B, C, D in 4 thread, They printf their name. I want use mutex to process A, B, C, D run in order A, B, C, D. This is my code but it don't work such as me think. How to they work?
#include <stdio.h>
#include <pthread.h>
void processA();
void processB();
void processC();
void processD();
pthread_mutex_t mutex;
void main(){
pthread_t thread1;
pthread_t thread2;
pthread_t thread3;
pthread_t thread4;
pthread_mutex_init(&mutex,NULL);
pthread_create(&thread1, NULL, (void *)&processA,NULL);
pthread_create(&thread2, NULL, (void *)&processB,NULL);
pthread_create(&thread3, NULL, (void *)&processC,NULL);
pthread_create(&thread4, NULL, (void *)&processD,NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
pthread_join(thread4, NULL);
pthread_mutex_destroy(&mutex);
}
void processA()
{
while (1)
{
pthread_mutex_lock(&mutex);
printf("A \n");
pthread_mutex_unlock(&mutex);
}
}
void processB()
{
while (1)
{
pthread_mutex_lock(&mutex);
printf("B \n");
pthread_mutex_unlock(&mutex);
}
}
void processC()
{
while (1)
{
pthread_mutex_lock(&mutex);
printf("C \n");
pthread_mutex_unlock(&mutex);
}
}
void processD()
{
pthread_mutex_lock(&mutex);
while (1)
{
pthread_mutex_lock(&mutex);
printf("D \n");
pthread_mutex_unlock(&mutex);
}
}
mutex is for creating mutual exclusion on some context. For example if you have an object that should be reached by one thread at a time, you can use mutex.
You should use 3 semaphores for implementing such feature. You can say:
//semaphore1 = up, semaphore2 = up, semaphore3 = up
//Thread A
//wait for semaphore1 is up
//work
//make semaphore1 down
//Thread B
//wait for semaphore1 is down
//work
//make semaphore2 down
//Thread C
//wait for semaphore2 is down
//work
//make semaphore3 down
//Thread D
//wait for semaphore3 is down
//work
Well this is how you can do it, you just use mutex for the mutual variable (f in this case) and a pthread conditional signal to trigger the action of one thread per second. All of the threads get the signal but only one can access the mutex.
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <stdlib.h>
#include <memory.h>
#include <stdarg.h>
#include <pthread.h>
pthread_mutex_t v1 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t v2 = PTHREAD_COND_INITIALIZER;
int f = 0;
void *processA(){
while(1){
pthread_mutex_lock(&v1);
pthread_cond_wait(&v2,&v1);
printf("A,%d\n",f);
f++;
pthread_mutex_unlock(&v1);
}
return NULL;
}
void *processB(){
while(1){
pthread_mutex_lock(&v1);
pthread_cond_wait(&v2,&v1);
printf("B,%d\n",f);
f++;
pthread_mutex_unlock(&v1);
}
return NULL;
}
void *processC(){
while(1){
pthread_mutex_lock(&v1);
pthread_cond_wait(&v2,&v1);
printf("C,%d\n",f);
f++;
pthread_mutex_unlock(&v1);
}
void main(){
pthread_t *h;
int i,ptnum = 3;
h = malloc(sizeof(pthread_t)*ptnum);
pthread_create(&h[0],NULL,processA,NULL);
pthread_create(&h[1],NULL,processB,NULL);
pthread_create(&h[2],NULL,processC,NULL);
while(f<=30){
pthread_cond_signal(&v2);
sleep(1);
}
pthread_mutex_lock(&v1);
printf("Main Mutex\n");
for(i=0;i<ptnum;i++){
pthread_join(&h[i],PTHREAD_CANCELED);
}
pthread_mutex_unlock(&v1);
return NULL;
}
I need to write a program for class that creates 8 threads. 4 producer, and 4 consumer. The producers need to loop, and randomly send SIGUSR1 or SIGUSR2 to all consumer threads. Only 2 should register if they have received SIGUSR1 and the other 2 register SIGUSR2.
When I try to run it all threads are created, "prod ready" is printed by all 4 producer threads,"waiting 1" is printed by both threads, but "waiting 2" is printed 3 times then all threads exit. At the end of debugging it says that the process exits normally.
I need to use semaphores to control the critical regions. Any help would be great.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <signal.h>
#define NP 4
#define NC1 2
#define NC2 2
#define CNT 10
void handler1(int signum);
void handler2(int signum);
typedef struct {
int sent;
int received;
int buf[1];
int SIG1;
int SIG2;
sem_t con;
sem_t prod;
} sbuf_t;
sbuf_t buff;
void *producer() {
printf("prod ready \n");
int s;
while(1){
sem_wait(&buff.prod);
s=rand()%2;
if(s==1){
buff.sent++;
kill(0,SIGUSR1);
}
else if(s==2){
buff.sent++;
kill(0,SIGUSR2);
}sem_post(&buff.prod);
}
}
void *consumer1() {
signal(SIGUSR1, handler1);
printf("waiting 1\n");
while(1){
}
}
void *consumer2() {
signal(SIGUSR2, handler2);
printf("waiting 2\n");
while(1){
}
}
void handler1(int signum){
if(signum==SIGUSR1){
sem_wait(&buff.con);
printf("Caught 1\n");
buff.received++;
buff.SIG1++;
sem_post(&buff.con);
}
}
void handler2(int signum){
if(signum==SIGUSR2){
sem_wait(&buff.con);
printf("caught 2 \n");
buff.received++;
buff.SIG2++;
sem_post(&buff.con);
}
}
void main(){
pthread_t threads[9];
buff.SIG1=0;
buff.SIG2=0;
buff.sent=0;
buff.received=0;
int index;
sem_init(&buff.con, 0, 0);
sem_init(&buff.prod, 0, 0);
for (index = 0; index < NP; index++) {
pthread_create(&threads[index], NULL, producer,NULL);
}
for (index = 0;index < NC1;index++) {
pthread_create(&threads[index+4], NULL, consumer1,NULL);
}
for (index = 0;index < NC2;index++) {
pthread_create(&threads[index+6], NULL, consumer2,NULL);
}
}
In the main() function, the threads are being created,
then main() exits.
When main() exits, all the threads are also exited.
Suggest reading about such functions as: pthread_exit() and pthread_join()
Note: the following has an error in the handling of the signals and in the handling of the semaphores, but will demonstrate the use of pthread_join() and pthread_exit()
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <signal.h>
#define NP 4
#define NC1 2
#define NC2 2
#define CNT 10
#define MAX_THREADS (9)
void handler1(int signum);
void handler2(int signum);
struct sbuf_t
{
int sent;
int received;
int buf[1];
int SIG1;
int SIG2;
sem_t con1;
sem_t con2;
sem_t prod;
};
typedef struct sbuf_t myData;
myData buff;
void *producer( void *dummy )
{
(void)dummy;
printf("prod ready \n");
int s;
while(1)
{
sem_wait(&buff.prod);
s=rand()%2;
if( !s )
{
buff.sent++;
kill( 0, SIGUSR1 );
}
else // if( s )
{
buff.sent++;
kill( 0, SIGUSR2 );
}
//sem_post(&buff.prod);
}
pthread_exit( NULL );
} // end thread: producer
void *consumer1( void *dummy )
{
(void)dummy;
//signal(SIGUSR1, handler1);
printf("waiting 1\n");
while(1)
{
sem_wait( &buff.con1 );
// do something
//sem_post( &buff.prod );
}
pthread_exit( NULL );
} // end thread: consumer1
void *consumer2( void *dummy )
{
(void)dummy;
//signal(SIGUSR2, handler2);
printf("waiting 2\n");
while(1)
{
sem_wait( &buff.con2 );
// do something
//sem_post( &buff.prod );
}
pthread_exit( NULL );
} // end thread: consumer2
void handler(int signum)
{
sem_post(&buff.prod);
if(signum==SIGUSR1)
{
//sem_wait(&buff.con);
puts("Caught 1");
buff.received++;
buff.SIG1++;
sem_post(&buff.con1);
}
else if(signum==SIGUSR2)
{
//sem_wait(&buff.con);
puts("caught 2");
buff.received++;
buff.SIG2++;
sem_post(&buff.con2);
}
} // end signal handler: handler2
int main( void )
{
pthread_t threads[ MAX_THREADS ];
buff.SIG1=0;
buff.SIG2=0;
buff.sent=0;
buff.received=0;
int index;
sem_init(&buff.con1, 0, 0);
sem_init(&buff.con2, 0, 0);
sem_init(&buff.prod, 0, 0);
signal(SIGUSR2, handler);
signal(SIGUSR1, handler);
for (index = 0; index < NP; index++)
{
pthread_create(&threads[index], NULL, producer,NULL);
}
for (index = 0;index < NC1;index++)
{
pthread_create(&threads[index+4], NULL, consumer1,NULL);
}
for (index = 0;index < NC2;index++)
{
pthread_create(&threads[index+6], NULL, consumer2,NULL);
}
for( size_t x=0; x<MAX_THREADS; x++ )
{
pthread_join( threads[x], NULL );
}
} // end function: main
HOWEVER, the methods to handle signals to threads does not use kill() as that is for processes.
rather the code should use functions similar to::
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
int pthread_cond_signal(pthread_cond_t *cond)
The signaled thread should block on a pthread_cond_wait() call until another thread sends a signal using pthread_cond_signal(), with the same condition variable.
Considering the analogy with signals delivered to processes, this is a bit different because the signaled thread has already suspended its execution waiting for a signal, unlike a process that simply gets interrupted and goes on.
For you example, you are creating your producers before your consumers. Also in your producer, you are using a random number generator to determine if you issue USR1 or USR2. Your description gave the impression you wanted two of each (versus some random mix totaling 4) which is what I see the code doing for you.