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
[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
相关文章推荐
- Linux下计划任务 crontab
- centos 下安装.net core
- Centos 7 相关操作与配置
- Linux操作系统基础解析之(三)——基本命令行操作及获得帮助的方法
- Linux系统资源监控--linux命令、nmon和spotlight
- 《Linux4.0设备驱动开发详解》笔记--第二十一章:Linux设备驱动的调试
- 《Linux4.0设备驱动开发详解》笔记--第二十章:Linux芯片级移植及底层驱动
- 《Linux4.0设备驱动开发详解》笔记--第十八章:ARM Linux设备树
- 《Linux4.0设备驱动开发详解》笔记--第十六章:USB主机、设备与Gadget驱动
- 不同系统的换行符号
- centos 7 安装配置mysql
- Linux用户切换
- linux 正则表达式
- centos 7 安装与配置java
- Linux中环境变量文件及配置
- 儿子该如何找老子要钱------浅聊linux中的5种I/O模型并顺便说说异步和非阻塞的区别
- LINUX下的Find命令的探索
- Linux 系列(二)——FTP安装手册
- linux下利用gcc编译C和C++
- 解决linux下WINDOWS下记事本乱码问题