您的位置:首页 > 运维架构 > Linux

linux基础编程 多线程中的互斥锁 pthread_mutex_lock

2016-05-21 13:45 651 查看
pthread_mutex.h头文件

[cpp] view
plaincopy

#ifndef __SEM_UTIL_H__  

#define __SEM_UTIL_H__  

  

typedef void* SemHandl_t;  

  

SemHandl_t MakeSem(); ///< Initialize the semaphore.  

int SemRelease(SemHandl_t hndlSem); ///< Unlock the semaphore.  

int SemWait(SemHandl_t hndlSem); ///< Lock the semaphore.  

int DestroySem(SemHandl_t hndlSem); ///< Destory the semaphore.  

  

  

#endif  

pthread_mutex.c源文件

[cpp] view
plaincopy

/* 

互斥锁用来保证一段时间内只有一个线程在执行一段代码。 

必要性显而易见:假设各个线程向同一个文件顺序写入数据, 

最后得到的结果一定是灾难性的。 

*/  

#include <stdio.h>  

#include <stdlib.h>  

#include <unistd.h>  

#include <pthread.h>  

  

#include "pthread_mutex.h"  

  

#define __DEBUG  

#ifdef __DEBUG  

#define DBG(fmt,args...) fprintf(stdout,  fmt,  ##args)  

#else  

#define DBG(fmt,args...)  

#endif  

#define ERR(fmt,args...) fprintf(stderr,  fmt,  ##args)  

  

/*线程互斥锁初始化*/  

SemHandl_t MakeSem()  

{  

    SemHandl_t hndlSem = malloc(sizeof(pthread_mutex_t));  

    if(hndlSem == NULL){  

        ERR("Not enough memory!!\n");  

        return NULL;  

    }  

    /* Initialize the mutex which protects the global data */  

    if(pthread_mutex_init(hndlSem, NULL) != 0){  

        ERR("Sem init faill!!\n");  

        free(hndlSem);  

        return NULL;  

    }  

    return hndlSem;  

}  

  

/*线程互斥锁释放*/  

int SemRelease(SemHandl_t hndlSem)  

{  

    if(hndlSem == NULL){  

        ERR("SemRelease: Invalid Semaphore handler\n");  

        return -1;  

    }  

    return pthread_mutex_unlock(hndlSem);  

}  

  

/*等待*/  

int SemWait(SemHandl_t hndlSem)  

{  

    if(hndlSem == NULL){  

        ERR("SemWait: Invalid Semaphore handler\n");  

        return -1;  

    }  

    return pthread_mutex_lock(hndlSem);  

}  

  

/*删除*/  

int DestroySem(SemHandl_t hndlSem)  

{  

    if(hndlSem == NULL){  

        ERR("DestroySem: Invalid Semaphore handler\n");  

        return -1;  

    }  

    pthread_mutex_lock(hndlSem);  

    pthread_mutex_unlock(hndlSem);  

    if(pthread_mutex_destroy(hndlSem) !=0){  

        ERR("Sem_kill faill!!\n");  

    }  

    free(hndlSem);  

    return 0;  

}  

有了以上基础就可以再多线程中测试了,下面的代码是在上篇文章的基础上修改的

thread.c 源文件

[cpp] view
plaincopy

#include <stdio.h>  

#include <stdlib.h>  

#include <unistd.h>  

#include <pthread.h>  

  

#include "pthread_mutex.h"  

  

#define __DEBUG  

#ifdef __DEBUG  

#define DBG(fmt,args...) fprintf(stdout,  fmt,  ##args)  

#else  

#define DBG(fmt,args...)  

#endif  

#define ERR(fmt,args...) fprintf(stderr,  fmt,  ##args)  

  

static int isThreadQuit = 0;  

SemHandl_t gHndlSem = NULL;  

  

/* 

某设备写操作,不同同时访问,所以所以需要线程锁保护 

1、将函数DeviceWrite中加锁 

2、在访问DeviceWrite的线程中加锁 

以上两种方法跟据需要选择其一。 

本例中在访问的线程中加锁 

*/  

void DeviceWrite(char *str)  

{  

    /*SemWait(gHndlSem);*/  

    DBG("Device Write: %s\n",str);  

    /*SemRelease(gHndlSem);*/  

}  

void SetXxThreadQuit()  

{     

    /*quit*/  

    isThreadQuit = 1;  

}  

void *XxManageThread(void *arg)  

{  

    char *cmd = (char*)arg;  

    DBG("arg value=%s\n",cmd);  

    while(isThreadQuit==0){  

        SemWait(gHndlSem);  

        DeviceWrite("thread 1");  

        SemRelease(gHndlSem);  

        sleep(1);  

    }  

    /*arg是将指针带进来,cmd则相反,或者设置 NULL*/  

    pthread_exit(cmd);  

    //pthread_exit(NULL);  

}  

void *XxManageThreadMutex(void *arg)  

{  

    char *cmd = (char*)arg;  

    DBG("arg value=%s\n",cmd);  

    while(isThreadQuit==0){  

        SemWait(gHndlSem);  

        DeviceWrite("thread 2");  

        SemRelease(gHndlSem);  

        sleep(1);  

    }  

    /*arg是将指针带进来,cmd则相反,或者设置 NULL*/  

    pthread_exit(cmd);  

    //pthread_exit(NULL);  

}  

  

int XxManageThreadInit()  

{  

    pthread_t tManageThread;  

    pthread_t tManageThreadMutex;  

      

    char *any="any value";  

    char *retn;  

    int ret;  

    /* 

      第二个参数是设置线程属性,一般很少用到(设置优先级等),第四个参数为传递到线程的指针, 

      可以为任何类型 

    */  

    ret = pthread_create(&tManageThread,NULL,XxManageThread,"1 thread");  

    if(ret == -1){  

        /*成功返回0.失败返回-1*/  

        ERR("Ctreate Thread ERROR\n");  

        return -1;  

    }  

  

    ret = pthread_create(&tManageThreadMutex,NULL,XxManageThreadMutex,"2 thread");  

    if(ret == -1){  

        /*成功返回0.失败返回-1*/  

        ERR("Ctreate Thread ERROR\n");  

        return -1;  

    }  

      

    /* 

      设置线程退出时资源的清理方式,如果是detach,退出时会自动清理 

      如果是join,则要等待pthread_join调用时才会清理 

    */  

    pthread_detach(tManageThread);  

    pthread_detach(tManageThreadMutex);  

    //pthread_join(tManageThread,retn);  

    //DBG("retn value=%s\n",retn);  

    return 0;  

}  

  

#define TEST_MAIN  

#ifdef TEST_MAIN  

int main()  

{  

    printf("hello liuyu\n");  

    int count=3;  

    /*创建线程锁*/  

    gHndlSem = MakeSem();  

    if(gHndlSem == NULL){  

        return -1;  

    }  

      

    if(XxManageThreadInit()==-1){  

        exit(1);  

    }  

      

    while(count--){  

        DBG("[0] main running\n");  

        sleep(2);  

    }  

      

    SetXxThreadQuit();  

    /*等待线程结束*/  

    sleep(1);  

    /*删除线程锁*/  

    DestroySem(gHndlSem);  

    DBG("waitting thread exit...\n");  

    return 0;  

}  

#endif  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: