免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1810 | 回复: 0
打印 上一主题 下一主题

Linux 线程学习 - 线程同步.互斥量 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-02-09 09:15 |只看该作者 |倒序浏览

                                                当多个线程共享使用同一段内存时,为了保证数据的一致性,就需要考虑到线程同步的
问题。
互斥量(mutex)
保证同一时间只有一个线程访问数据,在线程访问数据前先对数据加锁,这样数据只能
为该线程所用,其他试图对数据加锁的线程将被阻塞直到当前线程释放对该数据的锁。
        
#include
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
               const pthread_mutexattr_t *restrict attr);        成功返回0,否则返回错误编号
pthread_mutex_t 是互斥量的数据类型。用它定义了一个互斥量之后还需要对互斥量作
初始化。初始化可直接赋值(如下),也可调用pthread_mutex_init来进行初始化。
pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
pthread_mutex_t errchkmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
一个互斥量只有两个状态:unlocked(未上锁,不属于任一线程), locked(上锁,属于某
一线程)。一个互斥量不可能同时被两个不同的线程锁住。如果一个线程试图对某一互斥
量上锁,而该互斥量已为其他的线程锁住,则该线程会被阻塞直到该互斥量被释放。
pthread_mutex_init 用来初始化(mutex所指向的)互斥量,attr用来指定互斥量的属性。
如果不指定属性(attr为NULL),则使用默认的属性。
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
        成功返回0,否则返回错误编号
pthread_mutex_lock用于对互斥量上锁。
        如果该互斥量还未上锁,则对其上锁,且该互斥量就属于调用线程,
函数pthread_mutex_lock立即返回。
        如果该互斥量已经为别的线程锁住,则pthread_mutex_lock阻塞调用线程,
直到该互斥量释放。
        如果该互斥量已经被调用线程锁住,则调用线程再次用pthread_mutex_lock
该互斥量上锁时,处理过程与互斥量的类型有关。
fast - 调用线程阻塞,直到该锁释放。这样倒致调用线程死锁。
error checking - pthread_mutex_lock立即返回,错误码为EDEADLK。               
recursive - pthread_mutex_lock 函数成功执行,且记录下调用线程对该互斥量上锁的次数。
这样的话,解锁时pthread_mutex_unlock调用的次数也必须一致,这样才能将锁置为unlocked状态。
pthread_mutex_trylock 与pthread_mutex_lock很相似,但是当互斥量已上锁时,此函数
并不阻塞调用线程,此时它只会立即返回并附带错误码EBUSY。
pthread_mutex_unlock 释放指定的互斥量。
如果互斥量的属性是
        
fast - 将其置于unlocked状态
recursive - 对一个互斥量有一个上锁的计数器,此时使该计数器减1, 当计数器减到0时
则释放该互斥量,变为unlocked状态。
error checking -
        int pthread_mutex_destroy(pthread_mutex_t *mutex);
        成功返回0,否则返回错误编号
销毁一个互斥量对象,释放该互斥量的所持的一些资源。
               
               
                //example:
#include stdio.h>
#include stdlib.h>
#include pthread.h>
struct foo {
        int             f_count;
        pthread_mutex_t f_lock;
};
void
err_sys(const char *s)
{
        printf("%s\n", s);
        exit(-1);
}
struct foo *
foo_alloc(void)
{
        struct foo *fp;
        if ((fp = malloc(sizeof(struct foo))) != NULL) {
                fp->f_count = 1;
                if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
                        free(fp);
                        return NULL;
                }
        }
        return fp;
}
void
foo_hold(struct foo *fp)
{
        pthread_mutex_lock(&fp->f_lock);
        fp->f_count++;
        pthread_mutex_unlock(&fp->f_lock);
        printf("foo_hold f_count = %d\n", fp->f_count);
}
void
foo_rele(struct foo *fp)
{
        pthread_mutex_lock(&fp->f_lock);
        if (--fp->f_count == 0) {
                pthread_mutex_unlock(&fp->f_lock);
                pthread_mutex_destroy(&fp->f_lock);
                free(fp);
        } else
                pthread_mutex_unlock(&fp->f_lock);
        printf("        foo_rele f_count = %d\n", fp->f_count);
}
void *
foo1(void *fp)
{
        for (;;)
                foo_hold((struct foo *)fp);
}
void *
foo2(void *fp)
{
        for (;;)
                foo_rele((struct foo *)fp);
}
int
main(void)
{
        int err;
        pthread_t tid1, tid2;
        struct foo *tt;
        tt = foo_alloc();
        err = pthread_create(&tid1, NULL, foo1, (struct foo *)tt);
        if (err != 0)
                err_sys("pthread_create error");
        err = pthread_create(&tid2, NULL, foo2, (struct foo *)tt);
        if (err != 0)
                err_sys("pthread_create error");
        err = pthread_join(tid1, NULL);
        if (err != 0)
                err_sys("pthread_join error");
        err = pthread_join(tid2, NULL);
        if (err != 0)
                err_sys("pthread_join error");
        printf("\n---------- over -------------\n");
        exit(0);
}
               
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/93566/showart_2180430.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP