int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
#include //头文件
互斥锁的初始化
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
pthread_mutex_t: 定义互斥体机制完成多线程的互斥操作,该机制的作用是对某个需要互斥的部分,在进入时先得到互斥体,如果没有得到互斥体,表明互斥部分被其它线程拥有,此时欲获取互斥体的线程阻塞,直到拥有该互斥体的线程完成互斥部分的操作为止。
mutex:是指向要初始化的互斥锁的指针。
attr: 是指向属性对象的指针,该属性对象定义要初始化的互斥锁的属性。如果该指针为 NULL,则使用默认的属性。,默认属性为快速互斥锁
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL); //按缺省的属性初始化互斥体变量mutex
成功则返回0, 出错则返回错误编号.
pthead_mutex_t muetx = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_init(&mutex, NULL)
mutex 指向要销毁的互斥锁的指针
int pthread_mutex_destroy(pthread_mutex_t *mutex);
互斥锁销毁函数在执行成功后返回 0,否则返回错误码。
对共享资源的访问, 要对互斥量进行加锁, 如果互斥量已经上了锁, 调用线程会阻塞, 直到互斥量被解锁. 在完成了对共享资源的访问后, 要对互斥量进行解锁。
int pthread_mutex_lock(pthread_mutex_t *mutex);
返回值: 成功则返回0, 出错则返回错误编号.
int pthread_mutex_trylock(pthread_mutex_t *mutex);
说明: 具体说一下trylock函数, 这个函数是非阻塞调用模式, 也就是说, 如果互斥量没被锁住, trylock函数将把互斥量加锁, 并获得对共享资源的访问权限; 如果互斥量被锁住了, trylock函数将不会阻塞等待而直接返回EBUSY, 表示共享资源处于忙状态。
函数释放有参数mutex指定的mutex对象的锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);
返回值: 成功则返回0, 出错则返回错误编号.
由于共享、竞争而没有加任何同步机制,导致产生于时间有关的错误,造成数据混乱:
1、不使用互斥锁
#include
#include
#include
#include
#include
void *tfn(void *arg)
{
for(int i =0;i < 5;i++)
{
printf("hi, ");
sleep(1);
printf(" boy \n");
sleep(1);
}
return NULL;
}
int main(void)
{
pthread_t tid;
pthread_create(&tid, NULL, tfn, NULL);
for(int i =0;i < 5;i++)
{
printf("hello, ");
sleep(1);
printf(" girl\n");
sleep(1);
}
pthread_join(tid , NULL);
return 0;
}
2、使用互斥锁
#include
#include
#include
#include
#include
pthread_mutex_t mutex;
void *tfn(void *arg)
{
for(int i =0;i < 5;i++)
{
pthread_mutex_lock(&mutex);
printf("hi, ");
sleep(1);
printf(" boy \n");
pthread_mutex_unlock(&mutex);
sleep(1);
}
return NULL;
}
int main(void)
{
pthread_t tid;
pthread_mutex_init(&mutex, NULL);
pthread_create(&tid, NULL, tfn, NULL);
for(int i =0;i < 5;i++)
{
printf("hello, ");
sleep(1);
printf(" girl\n");
sleep(1);
}
pthread_mutex_destroy(&mutex);
pthread_join(tid , NULL);
return 0;
}
3、多个线程实验
#include
#include
#include
#include
pthread_mutex_t mutex;
int val = 0;
void *ThreadFunc(void *arg)
{
while(1)
{
pthread_mutex_lock(&mutex); /*获取互斥锁*/
int i = 0;
for(i = 0 ; i < 10000 ; i++)
{
val++;
}
printf("val = %d\n" , val);
pthread_mutex_unlock(&mutex); /*释放互斥锁*/
usleep(20);
}
return 0;
}
int main()
{
void *ResVal;
pthread_mutex_init (&mutex, NULL); /*定义*/
pthread_t thread1 , thread2;
pthread_create(&thread1 , NULL , ThreadFunc , NULL);
pthread_create(&thread2 , NULL , ThreadFunc , NULL);
pthread_join(thread1 , &ResVal);
pthread_join(thread2 , &ResVal);
}
若使用互斥锁,则val永远是以10000位单位自加,不使用互斥锁,输出结果无序,不可控。
1、https://www.cnblogs.com/biyeymyhjob/archive/2012/07/21/2602015.html
2、https://www.cnblogs.com/zhanghongfeng/p/10294975.html
3、https://blog.csdn.net/qq_24373811/article/details/52371792
4、https://blog.csdn.net/qq_39736982
5、https://blog.csdn.net/wssjn1994/article/details/86064852
6、https://www.cnblogs.com/jiu0821/p/6100824.html