线程同步--互斥量

线程的最大特点是资源的共享性,但资源共享中带来了对共享资源的竞争问题;解决竞争问题的途径是保证对共享资源的互斥访问,所谓互斥访问是指一个执行单元在访问共享资源的时候,他她的指向单元被禁止访问,以保证线程之间同步进行;同步是了保证在同一个时刻只有一个线程对资源进行操作,linux下提供了多种方式来处理线程同步,最常用的是互斥锁,条件变量和信号。

互斥量:

互斥量用pthread_mutex_t 数据类型来表示;操作函数集如下所示:

//该函数初始化一个互斥体变量,如果参数attr 为NULL,则互斥体变量mutex 使用默认的属性。
int
pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t* attr ); // 该函数用来锁住互斥体变量。如果参数mutex 所指的互斥体已经被锁住了,那么发出调用的线程将被阻塞直到其他线程对mutex 解锁。 int pthread_mutex_lock(pthread_mutex_t *mutex );
//该函数用来锁住mutex 所指定的互斥体,但不阻塞。如果该互斥体已经被上锁,该调用不会阻塞等待,而会返回一个错误代码。 int pthread_mutex_trylock( pthread_t *mutex);

//该函数用来对一个互斥体解锁。如果当前线程拥有参数mutex 所指定的互斥体,该调用将该互斥体解锁。 int pthread_mutex_unlock( pthread_mutex_t *mutex ); //该函数用来释放分配给参数mutex 的资源。调用成功时返回值为0, 否则返回一个非0 的错误代码。 int pthread_mutex_destroy (pthread_mutex_t *mutex );

下面是没有用互斥的实例:

#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#define FOR_COUNT 20
int myglobal;/*全局变量,主线程和子线程共享*/
void * thread_function(void *arg)/*线程函数*/
{
    int i,j;
    for(i = 0; i<FOR_COUNT; i++)
    {
        j = myglobal;
        j = j+1;
        fflush(stdout);
        sleep(1);
        myglobal = j;
        printf(".");    
        printf("thrad global = %d\n",myglobal);
    }
    return NULL;
}
int main()
{
    pthread_t mythread;
    int i;
    if(pthread_create(&mythread, NULL, thread_function, NULL))
    {
        printf("error creating thead.");
        abort();
    }
    /*主线程中对变量进行操作*/
    for(i=0; i < FOR_COUNT; i++)
    {
        myglobal = myglobal + 1;    
        printf("o");
        printf("main global = %d\n",myglobal);
        fflush(stdout);
        sleep(1);
    }
    if(pthread_join(mythread,NULL))
    {
        printf("error joining thread");
        abort();
    }
    printf("\n mygloabl equals %d\n", myglobal);
    exit(0);
}

结果如下所示:可以看出 两次程序运行的结果不一样,因为线程是并行的,不能假设调度策略;

omain global = 19    omain global = 27
.thrad global = 19   .thrad global = 27
omain global = 20    omain global = 28
.thrad global = 20   .thrad global = 29
omain global = 21    omain global = 30
.thrad global = 21   .thrad global = 31
omain global = 22o    main global = 32
.thrad global = 22   .thrad global = 33
mygloabl equals 22     mygloabl equals 33

 使用互斥量(例子1):静态分配互斥量

#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#define FOR_COUNT 20
int myglobal;
/* PTHREAD_MUTEX_INITIALIZER用于初始化静态分配的互斥量*/
pthread_mutex_t mutext = PTHREAD_MUTEX_INITIALIZER;
void * thread_function(void *arg)
{
    int i,j;
    for(i = 0; i<FOR_COUNT; i++)
    {
        pthread_mutex_lock(&mutext);
        j = myglobal;
        j = j+1;
        fflush(stdout);
        myglobal = j;
        printf(".");            
        printf("thrad global = %d\n",myglobal);
        pthread_mutex_unlock(&mutext);    
        sleep(1);//等待让另外一个线程运行
    }
    return NULL;
}
int main()
{
    pthread_t mythread;
    int i;
    if(pthread_create(&mythread, NULL, thread_function, NULL))
    {
        printf("error creating thead.");
        abort();
    }
    for(i=0; i < FOR_COUNT; i++)
    {
        pthread_mutex_lock(&mutext);
        myglobal = myglobal + 1;    
        printf("o");
        printf("main global = %d\n",myglobal); 
        pthread_mutex_unlock(&mutext);
        fflush(stdout);
        sleep(1);//等待让另外一个线程运行
    }
    if(pthread_join(mythread,NULL))
    {
        printf("error joining thread");
        abort();
    }
    pthread_mutex_destroy(&mutext);
    printf("\n mygloabl equals %d\n", myglobal);
    exit(0);
}

 使用互斥量(例子2):动态分配互斥量

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct foo
{
    int f_count;
    pthread_mutex_t f_lock;
};
struct foo * foo_alloc()
{
    struct  foo * fp;
    if((fp = (struct  foo *)malloc(sizeof(struct foo))) != NULL)
    {
        if(pthread_mutex_init(&fp->f_lock, NULL) != 0)
        {
            free(fp);
            return NULL;
        }
        fp->f_count = 1;
    }
    return fp;
}
void foo_hold(struct foo * fp)
{
    pthread_mutex_lock(&fp->f_lock);
    fp->f_count++;
    printf("thread %u,count is %d\n",(unsigned int)pthread_self(), fp->f_count);
    pthread_mutex_unlock(&fp->f_lock);
}
void foo_rele(struct foo *fp)
{
  pthread_t tid = pthread_self();
  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);
      printf("finally destory the global\n");
  }
  else
  {
     pthread_mutex_unlock(&fp->f_lock);
     printf("the thread %u doesn`t need the source\n", (unsigned int )tid);
  } 
}
void * pthread_fun1(void * fp)
{
    struct foo * pfoo = (struct foo *)fp;
    foo_hold(pfoo);
    sleep(2);
    foo_rele(pfoo);
    pthread_exit(NULL);
    printf("pthread1 exit\n");
}
void * pthread_fun2(void *fp )
{
    struct foo * pfoo = (struct foo *)fp;
    foo_hold(pfoo);
    sleep(1);
    foo_rele(pfoo);
    pthread_exit(NULL);
    printf("pthread2 exit\n");
}
int main()
{
    int err;
    pthread_t  thread1, thread2;
    /*分配全局变量*/
    struct foo * fp;
    fp = foo_alloc();
    err = pthread_create(&thread1, NULL,pthread_fun1, (void *)fp);
    if( err != 0 )
    {
        printf("cant not create thread1:%s\n", strerror(err));
        exit(1);
    }
    err = pthread_create(&thread2, NULL,pthread_fun2, (void *)fp);
    if( err != 0 )
    {
        printf("cant not create thread1:%s\n", strerror(err));
        exit(1);
    }
    sleep(1);
    foo_rele(fp);
    /*主线程等待子线程退出*/
    if(pthread_join(thread1,NULL) == 0)
        printf("pthrad1 exit\n");
    if(pthread_join(thread2,NULL) == 0 )
        printf("pthrad2 exit\n");
    exit(0);
}

程序运行结果:

thread 3079039856,count is 2
thread 3070647152,count is 3
the thread 3079042752 doesn`t need the source
the thread 3070647152 doesn`t need the source
finally destory the global
pthrad1 exit
pthrad2 exit

 

 

posted @ 2013-04-06 11:44  linengier  阅读(290)  评论(0编辑  收藏  举报