pthread 和访问临界区
pthread and accessing the critical section
好吧,下面的代码是针对两个线程的。我对互斥体有一些问题。
创建线程 t1 后,它调用 add_queue()。然后它会通知线程 t2 在其临界区工作。但是,程序不会为线程 t2 运行。
线程 t1 的 运行s 并在其临界区执行其工作。然后,我锁定了线程 t2 的互斥量。但是,程序卡在了第 29 行。
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
static int pending_requests =0;
static pthread_mutex_t prmutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t prcondition = PTHREAD_COND_INITIALIZER;
static int critical = 0;
int get_number_requests(void)
{
return pending_requests;
}
void add_queue()
{
pthread_mutex_lock(&prmutex);
pending_requests++;
critical++;
pthread_mutex_unlock(&prmutex);
printf("xxxx\n");
printf("critical=%d\n",critical);
}
void remove_from_queue()
{
pthread_mutex_lock(&prmutex);
pending_requests--;
printf("BBBBcritical=%d\n",critical);
critical--;
printf("BBBcritical=%d\n",critical);
pthread_mutex_unlock(&prmutex);
}
void *get_request()
{
add_queue();
if (get_number_requests() != 0)
{
printf("I have a element in the queue. Signalling to processor thread..\n");
pthread_cond_signal(&prcondition);
}
pthread_exit(0);
}
void *processor()
{
while(get_number_requests() == 0)
{
printf("BBB This is a processor thread, I am waiting..\n");
pthread_cond_wait(&prcondition,&prmutex);
}
while(get_number_requests() !=0)
{
printf("aaaa\n");
remove_from_queue();
pthread_cond_signal(&prcondition);
}
pthread_exit(0);
}
int main()
{
pthread_t t1,t2;
printf("critical=%d\n",critical);
pthread_create(&t1,NULL,get_request,NULL);
pthread_create(&t2,NULL,processor,NULL);
printf("critical=%d\n",critical);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
}
您对 pthread_cond_wait
的使用在很多方面都是错误的。仔细阅读 pthread_cond_wait
的 man page 将帮助您了解如何正确使用它。
在调用 pthread_cond_wait
之前,必须锁定互斥量。来自手册:
They shall be called with mutex locked by the calling thread or
undefined behavior results.
即调用pthread_cond_wait
前需要先调用pthread_mutex_lock
。
当 pthread_cond_wait
returns 时,它将锁定互斥量。来自手册:
Upon successful return, the mutex shall have been locked and shall be owned by the calling thread.
所以在remove_from_queue
中再次尝试锁定是错误的。由于互斥锁已经被锁定,remove_from_queue
中的 pthread_mutex_lock
调用将无限期地阻塞,正如您所发现的(即,线程自身已死锁)。
好吧,下面的代码是针对两个线程的。我对互斥体有一些问题。 创建线程 t1 后,它调用 add_queue()。然后它会通知线程 t2 在其临界区工作。但是,程序不会为线程 t2 运行。 线程 t1 的 运行s 并在其临界区执行其工作。然后,我锁定了线程 t2 的互斥量。但是,程序卡在了第 29 行。
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
static int pending_requests =0;
static pthread_mutex_t prmutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t prcondition = PTHREAD_COND_INITIALIZER;
static int critical = 0;
int get_number_requests(void)
{
return pending_requests;
}
void add_queue()
{
pthread_mutex_lock(&prmutex);
pending_requests++;
critical++;
pthread_mutex_unlock(&prmutex);
printf("xxxx\n");
printf("critical=%d\n",critical);
}
void remove_from_queue()
{
pthread_mutex_lock(&prmutex);
pending_requests--;
printf("BBBBcritical=%d\n",critical);
critical--;
printf("BBBcritical=%d\n",critical);
pthread_mutex_unlock(&prmutex);
}
void *get_request()
{
add_queue();
if (get_number_requests() != 0)
{
printf("I have a element in the queue. Signalling to processor thread..\n");
pthread_cond_signal(&prcondition);
}
pthread_exit(0);
}
void *processor()
{
while(get_number_requests() == 0)
{
printf("BBB This is a processor thread, I am waiting..\n");
pthread_cond_wait(&prcondition,&prmutex);
}
while(get_number_requests() !=0)
{
printf("aaaa\n");
remove_from_queue();
pthread_cond_signal(&prcondition);
}
pthread_exit(0);
}
int main()
{
pthread_t t1,t2;
printf("critical=%d\n",critical);
pthread_create(&t1,NULL,get_request,NULL);
pthread_create(&t2,NULL,processor,NULL);
printf("critical=%d\n",critical);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
}
您对 pthread_cond_wait
的使用在很多方面都是错误的。仔细阅读 pthread_cond_wait
的 man page 将帮助您了解如何正确使用它。
在调用
pthread_cond_wait
之前,必须锁定互斥量。来自手册:They shall be called with mutex locked by the calling thread or undefined behavior results.
即调用
pthread_cond_wait
前需要先调用pthread_mutex_lock
。当
pthread_cond_wait
returns 时,它将锁定互斥量。来自手册:Upon successful return, the mutex shall have been locked and shall be owned by the calling thread.
所以在
remove_from_queue
中再次尝试锁定是错误的。由于互斥锁已经被锁定,remove_from_queue
中的pthread_mutex_lock
调用将无限期地阻塞,正如您所发现的(即,线程自身已死锁)。