posts - 0,  comments - 3,  trackbacks - 0

一、什么是互斥锁

       另一种在多线程程序中同步访问手段是使用互斥量。程序员给某个对象加上一把“锁”,每次只允许一个

线程去访问它。如果想对代码关键部分的访问进行控制,你必须在进入这段代码之前锁定一把互斥量,在完成

操作之后再释放它。

 

       互斥量函数有

       pthread_mutex_init 初始化一个互斥量

       pthread_mutex_lock 给一个互斥量加锁

       pthread_mutex_trylock 加锁,如果失败不阻塞

       pthread_mutex_unlock 解锁

       互斥量从本质上说是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的

锁。对互斥量进行加锁以后,任何其他试图再次对互斥量加锁的线程将会被阻塞直到当前线程释放该互斥锁。

如果释放互斥锁时有多个线程阻塞,所以在该互斥锁上的阻塞线程都会变成可运行状态,第一个处于运行状态

的线程可以对互斥量加锁,其他线程再次被阻塞,等待互斥锁被释放。

      
       互斥量用pthread_mutex_t数据类型来表示,在使用互斥量以前,必须首先对它进行初始化,可以把

它置为常量
PTHREAD_MUTEX_INITIALIZER(只对静态分配的互斥量),也可以通过调用pthread_mutex_init

数进行初始化,如果动态地分配互斥量,那么释放内存前需要调用
pthread_mutex_destroy.

 

二、初始化/回收互斥锁

1

名称:

pthread_mutexattr_init

功能:

初始化互斥锁。

头文件:

#include <pthread.h>

函数原形:

int pthread_mutex_init(pthread_mutex_t * mutex,

const pthread_mutex_t *attr);

参数:

mutex 互斥量

attr     互斥锁属性

返回值:

若成功则返回0,否则返回错误编号。

      

 










         
    mutex是我们要锁住的互斥锁,attr是互斥锁的属性,可用相应的函数修改,我们在下章介绍,要用默认

的属性初始化互斥量,只需把
attr设置为NULL

 

2

名称:

pthread_mutex_destroy

功能:

销毁对互斥变量分配的资源

头文件:

#include <pthread.h>

函数原形:

int pthread_mutex_destroy(pthread_mutex_t *mutex);

参数:

 

返回值:

若成功则返回0,否则返回错误编号。












三、对互斥量加减锁

3

名称:

pthread_mutex_lock/ pthread_mutex_trylock/ pthread_mutex_unlock

功能:

对互斥量加/减锁

头文件:

#include <pthread.h>

函数原形:

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

参数:

 

返回值:

若成功则返回0,否则返回错误编号。
















     对互斥量进行加锁,需要调用
pthread_mutex_lock , 如果互斥量已经上锁,该线程就会阻塞直至互斥

量被解锁。对互斥量解锁,需要调用
pthread_mutex_unlock.

     如果线程不希望被阻塞,他可以使用pthread_mutex_trylock尝试对互斥量进行加锁。如果调用

pthread_mutex_trylock时互斥量处于未锁住状态,那么pthread_mutex_trylock将锁住互斥量,否则就会失

败,不能锁住互斥量,而返回
EBUSY

 

下面试例子可以证明对互斥量加锁的必要性:

我们先来看不加锁的程序。

#inlcude <stdio.h>

#include <pthread.h>

#inlcude <stdio.h>

#include <unistd.h>

 

void *thread_function(void *arg);

 

int run_now=1;   /*run_now代表共享资源*/

 

int main()

{

int print_count=0; /*用于控制循环*/

prhread_t   a_thread;

 

if(pthread_create(&a_thread,NULL,thread_function,NULL)!=0)   /*创建一个进程*/

{

    perror(“Thread createion failed”);

    exit(1);

}

 /**如果子线程创建成功后,主线程和子线程交替进行*/

while(print_count++<5)

{

    if(run_now==1) /主线程:如果run_now1就把它修改为2*/

    {

        printf(“main thread is run"n”);

        run_now=2;

    }

    else

    {

        printf(“main thread is sleep"n”);

        sleep(1);

    }

}

pthread_join(a_thread,NULL); /*等待子线程结束*/

exit(0);

}

 

void *thread_function(void *arg)

{

int print_count_inner=0;

 

while(print_count_inner++<5)

{

    if(run_now==2) /子线程:如果run_now1就把它修改为1*/

    {

        printf(“function thread is run"n”);

        run_now=1;

    }

    else

    {

        printf(“function thread is sleep"n”);

        sleep(1);

    }

}

pthread_exit(NULL);

}

 

运行上面程序的运行结果为:

function thread is sleep

main thread is run

main thread is sleep

main thread is sleep

function thread is run

function thread is sleep

main thread is run

main thread is sleep

function thread is run

function thread is sleep

我们可以看到main线程和function线程是交替运行的。它们都可以对run_now进行操作。

 

下面是加锁的程序。

#inlcude <stdio.h>

#include <pthread.h>

#inlcude <stdio.h>

 

void *thread_function(void *arg);

 

int run_now=1; /*run_now代表共享资源*/

pthread_mutex_t work_mutex; /*定义互斥量*/

 

int main()

{

int res;

int print_count1=0;

prhread_t a_thread;

 

if(pthread_mutex_init(&work_mutex,NULL)!=0) /*初始化互斥量*/

{

    perror(“Mutex init faied”);

    exit(1);

}

 

if(pthread_create(&a_thread,NULL,thread_function,NULL)!=0) /*创建新线程*/

{

    perror(“Thread createion failed”);

    exit(1);

}

 

if(pthread_mutex_lock(&work_mutex)!=0) /*对互斥量加锁*/

{

    preeor(“Lock failed”);

    exit(1);

}

else

    printf(“main lock"n”);

 

while(print_count1++<5)

{

    if(run_now==1) /主线程:如果run_now1就把它修改为2*/

    {

        printf(“main thread is run"n”);

        run_now=2;

    }

    else

    {

        printf(“main thread is sleep"n”);

        sleep(1);

    }

}

 

if(pthread_mutex_unlock(&work_mutex)!=0) /*对互斥量解锁*/

{

    preeor(“unlock failed”);

    exit(1);

}

else

    printf(“main unlock"n”);

 

pthread_mutex_destroy(&work_mutex); /*收回互斥量资源*/

pthread_join(a_thread,NULL); /*等待子线程结束*/

exit(0);

}

 /**子线程要 执行 的 函数*/

void *thread_function(void *arg)

{

int print_count2=0;

 

sleep(1);

if(pthread_mutex_lock(&work_mutex)!=0)

{

    perror(“Lock failed”);

    exit(1);

}

else

    printf(“function lock"n”);

while(print_count2++<5)

{

    if(run_now==2) /分进程:如果run_now1就把它修改为1*/

    {

        printf(“function thread is run"n”);

        run_now=1;

    }

    else

    {

        printf(“function thread is sleep"n”);

        sleep(1);

    }

}

 

if(pthread_mutex_unlock(&work_mutex)!=0) /*对互斥量解锁*/

{

    perror(“unlock failed”);

    exit(1);

}

else

    printf(“function unlock"n”);

pthread_exit(NULL);

}

 

下面是运行结果:

main lock

main thread is run

main thread is sleep

main thread is sleep

main thread is sleep

main thread is sleep

main unlock

function lock

function thread is run

function thread is sleep

function thread is sleep

function thread is sleep

function thread is sleep

function unlock

    我们从运行结果可以看到,主线程把占用互斥锁后,子线程在试图占用同一把互斥锁的时候,就会把被阻

塞,直到主线程unlock这把锁.只有在占用互斥锁后,才可以执行 后面的代码.

posted on 2009-09-30 00:18 月光记忆 阅读(863) 评论(0)  编辑  收藏 所属分类: c多线程学习

只有注册用户登录后才能发表评论。


网站导航:
 
<2024年12月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

留言簿(2)

随笔分类

文章分类

文章档案

搜索

  •  

最新评论