首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

线程同步——互斥量

线程同步——互斥量

同步的概念
多个线程可以共享内存空间,在程序中不可避免的需要多个线程协作完成某个功能。那么这些线程就可能会使用某个公共的资源。比如说全局变量,某个文件等等。为了不产生冲突,冲突会产生在多个线程的写操作之间,而读操作则很安全。这就需要多个线程之间的同步。
互斥量的原理
互斥量 实现同步的机制很好理解。可以将互斥量想象为锁。只有当一个线程获得该锁时才有权限对共享资源的操作。从而可以理解为该线程对共享资源上了一把锁,其他线程无权操作。在此线程操作完成之后,需要解锁以便其他线程可以获得该锁。可以想的出来,使用互斥量的代码结构应该是下面的这种形式:
复制代码
/* get the lock */
get_mutex();
/* some handler code */
...
/* release the lock */
release_mutex();
复制代码

值的注意的是,对于想要保护的共享资源,所有的线程都应该使用上面的代码形式,而不只是一两个线程使用互斥量。否则,还是会产生冲突。
接口函数
互斥量变量用 pthread_mutex_t 数据类型来表示。在对其使用之前必须初始化。有静态和动态两种初始化的方式。静态方式将其设置为常量 PTHREAD_MUTEX_INITIALIZER 动态方式需要借助下面两个函数:
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destory(pthread_mutx_t *mutex);
                    两个函数返回值:若成功,返回0;否则,返回错误编号
其中 attr 参数可以设置为 NULL 表示使用默认的初始化互斥量。
对互斥量进行加锁,需要调用 pthread_mutex_lock 如果互斥量已经上锁,调用线程将阻塞知道互斥量被解锁。对互斥量解锁,需要调用 pthread_mutex_unlock
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
                    两个函数返回值:若成功,返回0;否则,返回错误编
实例
互斥量的内容就这么多,写个例子来练习一下:
复制代码
#include <pthread.h>
#include <stdio.h>

int global = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *fun1(void *arg)
{
    int i = 0;
    for (; i < 50; i++)
    {
        pthread_mutex_lock(&mutex);      
        global += 1;
        printf("thread 1 write \t%d\n", global);
        pthread_mutex_unlock(&mutex);
    }
    pthread_exit((void*)1);
}
void *fun2(void *arg)
{
    int i = 0;
    for (; i < 50; i++)
    {
        pthread_mutex_lock(&mutex);      
        global += 1;
        printf("thread 2 write \t%d\n", global);
        pthread_mutex_unlock(&mutex);
    }
    pthread_exit((void*)2);
}

int main()
{
    pthread_t tid1, tid2;
    if (pthread_create(&tid1, NULL, fun1, NULL) != 0)
        return -1;
    if (pthread_create(&tid2, NULL, fun2, NULL) != 0)
        return -1;
    sleep(5);
    return 0;
}
继承事业,薪火相传
返回列表