1、互斥锁
用于解决竞争问题的一种机制。
什么是竞争,竞争就是多个实体同时获取一个资源,例如多个线程写一个全局变量。
2、Linux如何使用互斥锁
以pthread为例,锁的创建和使用如下:
2.1、创建互斥锁
1)使用静态方式创建锁
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
PTHREAD_MUTEX_INITIALIZER是一个宏,携带了锁的所有默认参数。
2)使用动态方式创建锁:
pthread_mutex_t lock = NULL;
pthread_mutex_init(&lock, NULL);
静态方式适用于创建全局资源锁,注意用语,锁本身是全局资源。动态方式则更加灵活,它可以在任务中创建锁,也可以创建使用malloc申请内存资源的锁。
2.2、互斥锁的使用
1)加锁
/* 加锁*/
pthread_mutex_lock(&lock);
2)解锁
/* 解锁 */
pthread_mutex_unlock(&lock);
【注意事项】加锁解锁是一对影形不离的兄弟,必须成对出现
2.3、互斥锁的释放
pthread_mutexattr_destroy(&lock)
lock = NULL;
锁也是一种资源,在线程退出,或者不再需要的时候,应该使用上面的destory函数将其释放,并将指针置空。
3、互斥锁实例
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <pthread.h>
/* global variable */
/* 全局变量 */
int gValue = 0;
/* mutex */
/* 创建互斥锁*/
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
/************************************
* 函数名:
* threadFuncReader
* 参数:
* void *arg
* fan
线程1:将
*/
void *threadFuncReader(void *arg)
{
while(1)
{
gValue = 1;
if(1 != gValue)
{
printf("\nerror");
}
usleep(1);
}
}
void *threadFuncWriter(void *arg)
{
while(1)
{
gValue = 2;
if(2 !=gValue )
{
printf("\nerror");
}
usleep(1);
}
}
void *threadFuncWriter1(void *arg)
{
while(1)
{
gValue = 3;
if(3 != gValue )
{
printf("\nerror");
}
else
{
//printf("\nthis is [3], read value is [%d]", gValue);
}
usleep(1);
}
}
void *threadFuncWriter2(void *arg)
{
while(1)
{
gValue = 4;
if(4 != gValue )
{
printf("\nerror");
}
else
{
printf("\nthis is [4], read value is [%d]", gValue);
}
sleep(1);
}
}
int main(int argc, int **argv)
{
/* shared resources */
/* 创建线程 */
pthread_t tid_reader;
pthread_t tid_writer;
pthread_t tid_writer1;
pthread_t tid_writer2;
pthread_create(&tid_reader, NULL, threadFuncReader, NULL);
pthread_create(&tid_writer, NULL, threadFuncWriter, NULL);
pthread_create(&tid_writer1, NULL, threadFuncWriter1, NULL);
pthread_create(&tid_writer2, NULL, threadFuncWriter2, NULL);
/* 自动回收 */
pthread_join(tid_reader, NULL);
pthread_join(tid_writer, NULL);
pthread_join(tid_writer1, NULL);
pthread_join(tid_writer2, NULL);
printf("\n hello world in Linux.");
return 0;
}
上述代码由于没有锁,运行结果如下:
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
error
this is [4], read value is [4]
加锁后的代码:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <pthread.h>
/* global variable */
int gValue = 0;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void *threadFuncReader(void *arg)
{
while(1)
{
pthread_mutex_lock(&lock);
gValue = 1;
if(1 != gValue)
{
printf("\nerror");
}
// printf("\nthis is [1], read value is [%d]", gValue);
pthread_mutex_unlock(&lock);
usleep(1);
}
}
void *threadFuncWriter(void *arg)
{
while(1)
{
pthread_mutex_lock(&lock);
gValue = 2;
if(2 !=gValue )
{
printf("\nerror");
}
else
{
// printf("\nthis is [2], read value is [%d]", gValue);
}
pthread_mutex_unlock(&lock);
usleep(1);
}
}
void *threadFuncWriter1(void *arg)
{
while(1)
{
pthread_mutex_lock(&lock);
gValue = 3;
if(3 != gValue )
{
printf("\nerror");
}
else
{
//printf("\nthis is [3], read value is [%d]", gValue);
}
pthread_mutex_unlock(&lock);
usleep(1);
}
}
void *threadFuncWriter2(void *arg)
{
while(1)
{
pthread_mutex_lock(&lock);
gValue = 4;
if(4 != gValue )
{
printf("\nerror");
}
else
{
printf("\nthis is [4], read value is [%d]", gValue);
}
pthread_mutex_unlock(&lock);
sleep(1);
}
}
int main(int argc, int **argv)
{
/* shared resources */
pthread_t tid_reader;
pthread_t tid_writer;
pthread_t tid_writer1;
pthread_t tid_writer2;
pthread_create(&tid_reader, NULL, threadFuncReader, NULL);
pthread_create(&tid_writer, NULL, threadFuncWriter, NULL);
pthread_create(&tid_writer1, NULL, threadFuncWriter1, NULL);
pthread_create(&tid_writer2, NULL, threadFuncWriter2, NULL);
pthread_join(tid_reader, NULL);
pthread_join(tid_writer, NULL);
pthread_join(tid_writer1, NULL);
pthread_join(tid_writer2, NULL);
printf("\n hello world in Linux.");
return 0;
}
运行结果:
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]