Lock/Unlock mutex from two threads

I am have problem lock/unlock mutex in two separate threads. Following
is my code:

mutex_init(&(settings.mutex));
mutex_request(&(settings.mutex));
rc = thread_create(&(ListenThread), (thread_function
)thread1,&settings);
/
wait for the first thread to start up */
mutex_request(&(settings.mutex)); mutex_release(&(settings.mutex));
rc = thread_create(&(hTransmitThread), (wg_thread_function
*)thread2,&settings);

Inside thread1 I have code to set the parameters on the struct settings,
and then
called mutex_release(&(settings.mutex)).

In thread2, I check if that parameter is set, if it is, continue the
process
otherwise, exit the thread2.

This doesn’t seem to work, the parameter is often not set when the
thread2 started.
Of cause, if I add sleep(1) in between these creating thread, everything
works.

My question is that does the QNX require both lock and unlock the mutex
in the
same thread? How do I get this to work?

Here is the mutex request/release code.
void wg_mutex_init(wg_mutex * p_mutex)
{
if (p_mutex==NULL) {
return;
}
pthread_mutex_init(&p_mutex->mutex,NULL);
p_mutex->p_cond=NULL;
}
void wg_mutex_request(wg_mutex * p_mutex)
{
if (p_mutex==NULL){
return;
}
pthread_mutex_lock(&p_mutex->mutex);
}

void wg_mutex_release(wg_mutex * p_mutex)
{
if (p_mutex==NULL) {
return;
}
pthread_mutex_unlock(&p_mutex->mutex);
}

Thanks for any of your help.

-Beth

You “assumed” that if you lock a mutex, and lock it again (in same thread),
it will block (until another guy unblock it). This is absulotely not true.

Your “mutex_request()” function trashed the return value from
pthread_mutex_lock()
call. That is very bad. If you actually check the return value, you will
find
the second pthread_mutex_lock() actually returning EDEADLOCK.
If you read the lib reference carefully, this is the standard POSIX behavor.
That if a thread try to re-lock a mutex while it already owns it.

To you second question, “does mutex lock and unlock has to be same thread”?
The pthread_mutex_unlock() document clearly stated the answer is YES.
Otherwise, a EPERM will return. (which, also trashed by your
request_release())
call.

About how to make you program work. I think you probably want to
look at pthread_cond_* functions.

-xtang



Beth <id@address.com> wrote in message news:3E8E0EEA.20ED2463@address.com

I am have problem lock/unlock mutex in two separate threads. Following
is my code:

mutex_init(&(settings.mutex));
mutex_request(&(settings.mutex));
rc = thread_create(&(ListenThread), (thread_function
)thread1,&settings);
/
wait for the first thread to start up */
mutex_request(&(settings.mutex)); mutex_release(&(settings.mutex));
rc = thread_create(&(hTransmitThread), (wg_thread_function
*)thread2,&settings);

Inside thread1 I have code to set the parameters on the struct settings,
and then
called mutex_release(&(settings.mutex)).

In thread2, I check if that parameter is set, if it is, continue the
process
otherwise, exit the thread2.

This doesn’t seem to work, the parameter is often not set when the
thread2 started.
Of cause, if I add sleep(1) in between these creating thread, everything
works.

My question is that does the QNX require both lock and unlock the mutex
in the
same thread? How do I get this to work?

Here is the mutex request/release code.
void wg_mutex_init(wg_mutex * p_mutex)
{
if (p_mutex==NULL) {
return;
}
pthread_mutex_init(&p_mutex->mutex,NULL);
p_mutex->p_cond=NULL;
}
void wg_mutex_request(wg_mutex * p_mutex)
{
if (p_mutex==NULL){
return;
}
pthread_mutex_lock(&p_mutex->mutex);
}

void wg_mutex_release(wg_mutex * p_mutex)
{
if (p_mutex==NULL) {
return;
}
pthread_mutex_unlock(&p_mutex->mutex);
}

Thanks for any of your help.

-Beth

Beth <id@address.com> wrote:

I am have problem lock/unlock mutex in two separate threads.
My question is that does the QNX require both lock and unlock the mutex
in the same thread? How do I get this to work?

Yes, the thread that locks a mutex must be the one to unlock it;
obviously it wouldn’t be much of a MUTual EXclusion! Typically
you use a mutex to protect critical sections of code, like setting
a global structure or manipulating a linked list, and not to
synchronise threads. A semaphore or barrier is a better choice
of synchronisation object for that task.

/* wait for the first thread to start up */

You could do something like (there are other ways too):

/* In the main thread … */
sem_init(&thread_start_sem, 0, 0);
pthread_create();
sem_wait(&thread_start_sem); // this blocks until the post below

/* And in thread2 - the one created above … */
sem_post(&thread_start_sem);

Thanks for your response. I am trying to use the pthread_cond_* functions as you
suggested and I am having
difficulty to get it working. The pthread_cond_init returned 0, and
pthread_cond_wait never came back.
The program was hung… I can’t slay the process.

Here is the code…
mutex_init(&(settings.mutex));
mutex_cond_wait(&(settings.mutex));
/* release cond_mutex in the thread1 */
rc = thread_create(&(ListenThread), (thread_function *)thread1,&settings);
rc = thread_create(&(hTransmitThread), (wg_thread_function
*)thread2,&settings);

thread1{
/* release cond_mutex in the thread1 */
wg_mutex_cond_signal(&(c->mutex));
}

void mutex_cond_wait(m_mutex * p_mutex)
{
int rc=0;
if (p_mutex==NULL) {
return;
}
mutex_request(p_mutex);
if (p_mutex->p_cond){
mutex_release(p_mutex);
return;
}

/* create the conditional /
p_mutex->p_cond=malloc(sizeof(pthread_cond_t));
rc = pthread_cond_init(p_mutex->p_cond,NULL);
printf(“pthread_cond_init rc=%d\n”, rc);
/
do the wait */
rc = pthread_cond_wait(p_mutex->p_cond,&p_mutex->mutex);
printf(" pthread_cond_wait rc=%d\n", rc);

/* destroy the conditional */
rc = pthread_cond_destroy(p_mutex->p_cond);
free(p_mutex->p_cond);
p_mutex->p_cond=NULL;
mutex_release(p_mutex);
}
void mutex_cond_signal(m_mutex *p_mutex)
{
int rc=0;
if (p_mutex==NULL) {
return;
}
mutex_request(p_mutex);
if (p_mutex->p_cond)
{
rc = pthread_cond_broadcast(p_mutex->p_cond);
printf(“pthread_cond_broadcast rc=%d\n”, rc);
}
mutex_release(p_mutex);
}

The m_mutex is defined as:
typedef struct m_mutex
{
pthread_mutex_t mutex;
pthread_cond_t * p_cond;
} m_mutex;



Xiaodan Tang wrote:

You “assumed” that if you lock a mutex, and lock it again (in same thread),
it will block (until another guy unblock it). This is absulotely not true.

Your “mutex_request()” function trashed the return value from
pthread_mutex_lock()
call. That is very bad. If you actually check the return value, you will
find
the second pthread_mutex_lock() actually returning EDEADLOCK.
If you read the lib reference carefully, this is the standard POSIX behavor.
That if a thread try to re-lock a mutex while it already owns it.

To you second question, “does mutex lock and unlock has to be same thread”?
The pthread_mutex_unlock() document clearly stated the answer is YES.
Otherwise, a EPERM will return. (which, also trashed by your
request_release())
call.

About how to make you program work. I think you probably want to
look at pthread_cond_* functions.

-xtang

Beth <> id@address.com> > wrote in message news:> 3E8E0EEA.20ED2463@address.com> …
I am have problem lock/unlock mutex in two separate threads. Following
is my code:

mutex_init(&(settings.mutex));
mutex_request(&(settings.mutex));
rc = thread_create(&(ListenThread), (thread_function
)thread1,&settings);
/
wait for the first thread to start up */
mutex_request(&(settings.mutex)); mutex_release(&(settings.mutex));
rc = thread_create(&(hTransmitThread), (wg_thread_function
*)thread2,&settings);

Inside thread1 I have code to set the parameters on the struct settings,
and then
called mutex_release(&(settings.mutex)).

In thread2, I check if that parameter is set, if it is, continue the
process
otherwise, exit the thread2.

This doesn’t seem to work, the parameter is often not set when the
thread2 started.
Of cause, if I add sleep(1) in between these creating thread, everything
works.

My question is that does the QNX require both lock and unlock the mutex
in the
same thread? How do I get this to work?

Here is the mutex request/release code.
void wg_mutex_init(wg_mutex * p_mutex)
{
if (p_mutex==NULL) {
return;
}
pthread_mutex_init(&p_mutex->mutex,NULL);
p_mutex->p_cond=NULL;
}
void wg_mutex_request(wg_mutex * p_mutex)
{
if (p_mutex==NULL){
return;
}
pthread_mutex_lock(&p_mutex->mutex);
}

void wg_mutex_release(wg_mutex * p_mutex)
{
if (p_mutex==NULL) {
return;
}
pthread_mutex_unlock(&p_mutex->mutex);
}

Thanks for any of your help.

-Beth

John, thanks for your suggestion.

-Beth

John Garvey wrote:

Beth <> id@address.com> > wrote:
I am have problem lock/unlock mutex in two separate threads.
My question is that does the QNX require both lock and unlock the mutex
in the same thread? How do I get this to work?

Yes, the thread that locks a mutex must be the one to unlock it;
obviously it wouldn’t be much of a MUTual EXclusion! Typically
you use a mutex to protect critical sections of code, like setting
a global structure or manipulating a linked list, and not to
synchronise threads. A semaphore or barrier is a better choice
of synchronisation object for that task.

/* wait for the first thread to start up */

You could do something like (there are other ways too):

/* In the main thread … */
sem_init(&thread_start_sem, 0, 0);
pthread_create();
sem_wait(&thread_start_sem); // this blocks until the post below

/* And in thread2 - the one created above … */
sem_post(&thread_start_sem);