互斥锁
互斥锁也是属于线程之间处理同步互斥方式,有上锁/解锁两种状态。
互斥锁函数接口
1)初始化互斥锁
pthread_mutex_init()
man 3 pthread_mutex_init
(找不到的情况下首先
sudo apt-get install glibc-doc
sudo apt-get install manpages-posix-dev)
动态初始化
int pthread_mutex_init(pthread_mutex_t *mutex,
const pthread_mutexattr_t *attr);
mutex: pthread_mutex_t 互斥锁的数据类型
attr: 锁的属性,普通属性默认是阻塞锁 NULL
失败返回错误码
静态初始化 默认属性 NULL
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
如果属性是普通属性,则静态初始化与动态初始化一致。
初始化完结果: 锁被创建并且已经处于解锁的状态。
2)上锁 pthread_mutex_lock
man 3 pthread_mutex_lock
mutex: 必须已经初始化过的互斥锁的地址,并且锁解锁状态才能返回!
失败f返回错误码
3)解锁 pthread_mutex_unlock
man 3 pthread_mutex_unlock
mutex: 必须已经初始化过的互斥锁的地址,并且锁上锁状态才能返回!
失败返回错误码
4)销毁互斥锁 pthread_mutex_destroy()
man 3 pthread_mutex_destroy
mutex: 必须已经初始化过的互斥锁的地址
失败返回错误码
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; //静态初始化
void *Jack_fun(void *arg)
{
char *p = (char *)arg;
while(1)
{
//发消息的Jack,必须先上锁
pthread_mutex_lock(&m);
fgets(p,1024,stdin);
//解锁
pthread_mutex_unlock(&m);
if(strncmp(p,"quit",4) == 0)
{
break;
}
usleep(100000);
}
pthread_exit(NULL);
}
void *Rose_fun(void *arg)
{
usleep(100000);
char *p = (char *)arg;
while(1)
{
//接收消息的Rose,后上锁
pthread_mutex_lock(&m);
printf("from Jack = %s",p);
//解锁
pthread_mutex_unlock(&m);
if(strncmp(p,"quit",4) == 0)
{
break;
}
usleep(200000);
}
pthread_exit(NULL);
}
int main()
{
//1. 申请key值
key_t key = ftok(".",10);
//2. ID
int shmid = shmget(key,1024,IPC_CREAT|0666);
//3. 映射
char *p = shmat(shmid,NULL,0);
//4. 两个子线程
pthread_t Jack_tid,Rose_tid;
pthread_create(&Jack_tid,NULL,Jack_fun,(void *)p);
pthread_create(&Rose_tid,NULL,Rose_fun,(void *)p);
//5. 接合线程
pthread_join(Jack_tid,NULL);
pthread_join(Rose_tid,NULL);
//6. 撤销内存
shmdt(p);
shmctl(shmid,IPC_RMID,NULL);
//7. 锁
pthread_mutex_destroy(&m);
return 0;
}