线程互斥锁
只能解决单个共享资源的互斥问题
cpp
头文件:#include <pthread.h>
类型:pthread_mutex_t
PTHREAD_MUTEX_INITIALIZER 初始化
初始化:int pthread_mutex_init(pthread_mutex_t * mutex, NULL);
清理:int pthread_mutex_destroy(pthread_mutex_t * mutex);
阻塞P操作: int pthread_mutex_lock(pthread_mutex_t * mutex);
非阻塞P操作: int pthread_mutex_trylock(pthread_mutex_t * mutex);
检查锁状态,无论是已上锁还是未上锁均立即返回,只是返回的值不同,不会阻塞,循环调用该函数可以实现轮询等待
V操作: int pthread_mutex_unlock(pthread_mutex_t * mutex);
功能:见函数名
返回值:成功0,失败错误码
**问题:**主线程动态创建一个对象,该对象将可能被用于多个分离的新线程,要求确保每个线程用该对象时该对象必须存在,大家都不用该对象时才被销毁
算法:
代码:
myobject.h
cpp
#ifndef _MYOBJECT_H
#define _MYOBJECT_H
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
typedef int DT;
struct myobject{
DT data;
int refcnt;
pthread_mutex_t lock;
};
struct myobject *create_myobject(); // create
int add_object_refcnt(struct myobject *pobj); // add
int destroy_myobject(struct myobject *pobj); // destroy
#endif
myobject.c
cpp
#include "myobject.h"
struct myobject *create_myobject(){
struct myobject *pobj = (struct myobject *)malloc(sizeof(struct myobject));
if(pobj == NULL){
printf("malloc for a myobject failed\n");
return NULL;
}
memset(pobj,0,sizeof(struct myobject)); // 初始化
pthread_mutex_init(&(pobj->lock), NULL); // init
return pobj;
}
int add_object_refcnt(struct myobject *pobj){
int cnt = 0;
pthread_mutex_lock(&pobj->lock); // lock
cnt = ++pobj->refcnt; // cnt++
pthread_mutex_unlock(&pobj->lock); // unlock
return cnt;
}
int destroy_myobject(struct myobject *pobj){
pthread_mutex_lock(&pobj->lock); // lock
pobj->refcnt--; // cnt--
if(pobj->refcnt == 0){
pthread_mutex_destroy(&pobj->lock); // pthread_mutex_destroy()
free(pobj);
pobj = NULL;
printf("Destroy success\n");
return 0;
}
pthread_mutex_unlock(&pobj->lock); // unlock
return 0;
}
main.c
cpp
#include "myobject.h"
void *pthread_start1(void *parg); // thread1
void *pthread_start2(void *parg); // thread2
int main(){
pthread_t id[2]; // id
int ret = 0;
struct myobject *pobj;
pobj = create_myobject(); // create
add_object_refcnt(pobj); // main cnt +1
add_object_refcnt(pobj); // thread1 cnt +1
ret = pthread_create(&id[0],NULL,pthread_start1,(void*)pobj); // thread1
add_object_refcnt(pobj); // thread2 cnt +1
ret += pthread_create(&id[1],NULL,pthread_start2,(void*)pobj); // thread2
if(ret){
printf("pthread_create failed\n");
return 1;
}
pobj->data = 99;
printf("main thread:%d\n",pobj->data);
printf("cnt:%d\n",pobj->refcnt); // print
destroy_myobject(pobj); // destroy
pthread_exit(NULL); // main exit
return 0;
}
void *pthread_start1(void* parg){ // thread1
int ret = 0;
ret = pthread_detach(pthread_self()); // 线程分离
struct myobject *pobj;
pobj = (struct myobject*)parg;
pobj->data = 111;
printf("thread1:%d\n",pobj->data); // print
printf("cnt:%d\n",pobj->refcnt); // print
ret += destroy_myobject(pobj); // destroy
if(ret){
printf("destroy_myobject failed\n");
return NULL;
}
return NULL;
}
void *pthread_start2(void* parg){ // thread2
int ret = 0;
ret = pthread_detach(pthread_self()); // 线程分离
struct myobject *pobj = (struct myobject *)parg;
pobj->data = 222;
printf("thread2:%d\n",pobj->data); // print
printf("cnt:%d\n",pobj->refcnt); // print
ret += destroy_myobject(pobj); // destroy
if(ret){
printf("destroy_myobject failed\n");
return NULL;
}
return NULL;
}
输出: