ITPub博客

首页 > Linux操作系统 > Linux操作系统 > POSIX线程-(四)

POSIX线程-(四)

原创 Linux操作系统 作者:mylxiaoyi 时间:2009-08-10 19:16:00 0 删除 编辑

使用互斥同步

在多线程程序中同步访问的另一个方法就是使用互斥,其作用允许程序锁住一个对象,从而只有一个线程可以访问他。要控制对临界区代码的访问,在我们进入这段代码之前锁住一个互斥量,并且在我们完成操作时进行解锁。

使用互斥所需要基本函数与信号量所需要的函数相似,其声明如下:

#include
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t
*mutexattr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);

如平常一样,成功时返回0,如果失败则会返回一个错误代码,但是并没有设置errno;我们必须使用返回代码。

与信号量相类似,这些函数以一个指向前面声明的对象的指针为参数,在互斥方法是一个pthread_mutex_t。额外的属性参数pthread_mutexattr_t允许我们为互斥提供属性,这可以控制其行为。属性类型默认为"fast"。这有一个小的缺点,如果我们的程序试着在一个已经上锁的互斥量上调用pthread_mutex_lock,程序就会阻塞。因为拥有锁的线程现在被阻塞了,互斥量就不会被解锁,从而程序就会进入死锁状态。可以修改互斥量的属性,从而他或者可以检测这种情况并返回一个错误,或者是循环操作并且在同一个线程上允许多个锁。

设置互斥量的属性超出了本书的范围,所以我们会为属性指针传递NULL并且使用默认行为。我们可以通过阅读pthread_mutex_init手册页了解修改属性的内容。

试验--线程互斥

再一次说明,下面的程序是我们原始程序thread1.c的修改版,但是进行了大量的修改。这一次,我们有一些偏狂来访问我们的临界变量,并且使用一个互斥量来保证每次只有一个线程访问他们。为了使得代码更易于阅读,我们忽略了由互斥量加锁与解锁操作返回值的错误检测。在生产代码中,我们应该检测这些返回值。下面是这个新程序,thread4.c:

#include
#include
#include
#include
#include
#include

void *thread_function(void *arg);
pthread_mutex_t work_mutex;

#define WORK_SIZE 1024
char work_area[WORK_SIZE];
int time_to_exit = 0;

int main()
{
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_mutex_init(&work_mutex,NULL);
if(res != 0)
{
perror("Mutex initialization failed");
exit(EXIT_FAILURE);
}
res = pthread_create(&a_thread,NULL,thread_function,NULL);
if(res != 0)
{
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
pthread_mutex_lock(&work_mutex);
printf("Input some text, Enter 'end' to finish\n");
while(!time_to_exit)
{
fgets(work_area,WORK_SIZE,stdin);
pthread_mutex_unlock(&work_mutex);
while(1)
{
pthread_mutex_lock(&work_mutex);
if(work_area[0] != '\0')
{
pthread_mutex_unlock(&work_mutex);
sleep(1);
}
else
{
break;
}
}
}
pthread_mutex_unlock(&work_mutex);
printf("\nWaiting for thread to finish...\n");
res = pthread_join(a_thread,&thread_result);
if(res != 0)
{
perror("Thread join failed");
exit(EXIT_FAILURE);
}
printf("Thread joined\n");
pthread_mutex_destroy(&work_mutex);
exit(EXIT_SUCCESS);
}

void *thread_function(void *arg)
{
sleep(1);
pthread_mutex_lock(&work_mutex);
while(strncmp("end",work_area,3) != 0)
{
printf("You input %d characters\n",strlen(work_area)-1);
work_area[0] = '\0';
pthread_mutex_unlock(&work_mutex);
sleep(1);
pthread_mutex_lock(&work_mutex);
while(work_area[0] == '\0')
{
pthread_mutex_unlock(&work_mutex);
sleep(1);
pthread_mutex_lock(&work_mutex);
}
}
time_to_exit = 1;
work_area[0] = '\0';
pthread_mutex_unlock(&work_mutex);
pthread_exit(0);
}

$ cc -D_REENTRANT -I/usr/include/nptl thread4.c

Link URL: http://mylxiaoyi.javaeye.com/blog/430271

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/13670711/viewspace-611802/,如需转载,请注明出处,否则将追究法律责任。

下一篇: POSIX线程(三)
请登录后发表评论 登录
全部评论

注册时间:2008-07-09

  • 博文量
    25
  • 访问量
    10830