Linux--线程--互斥锁

1.互斥量
a)互斥量(mutex)从本质上来说是一把锁,一般在主线程中定义一个互斥量,就是定义一把锁。然后根据我们的需求来对线程操作这把锁。

b)如果给所有的线程都加上锁了,线程们会去争取内存空间,谁先争取到谁先运行,直到该线程解锁后,期间其他线程只能等待阻塞。

c)因为主线程不上锁,在先拿到锁的线程在跑的过程中,主线程也会跟着跑。
 

include
// 返回:若成功返回0,否则返回错误编号
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);创建锁
int pthread_mutex_lock(pthread_mutex_t *mutex);//加锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);//解锁
int pthread_mutex_destroy(pthread_mutex_t *mutex);//销毁锁
 

     互斥量用pthread_mutex_t数据类型表示。在使用互斥量前必须对它进行初始化,可以通过调用pthread_mutex_init函数进行初始化。如果动态地分配互斥量(例如通过调用malloc函数),那么在释放内存前需要调用 pthread_mutex_destroy.

  要用默认的属性初始化互斥量,只需要把attr设置为NULL。
   

锁:如果线程不希望被阻塞,它可以使用pthread_mutex_trylock尝试对互斥量进行加锁。如果调用pthread_mutex_trylock时互斥量处于未锁住状态,那么pthread_mutex_trylock将锁住互斥量,不会出现阻塞并返回0,否则pthread_mutex_trylock就会失败,不能锁住互斥量,而返回EBUSY。

2.加锁解锁简单操作:

代码:

#include
#include
#include 

int data = 0;//定义一个全局变量data 
pthread_mutex_t mutex;//创建一把锁 
void *func1(void *arg)
{
        int i;
        pthread_mutex_lock(&mutex);//加锁

        for(i=0;i<5;i++){
                printf("t1:thread id is:%ld\n",(unsigned long)pthread_self());
                printf("t1:is param:%d\n",*((int *)arg));
                sleep(1);
        }

        pthread_mutex_unlock(&mutex);//解锁
}
void *func2(void *arg)
{
        pthread_mutex_lock(&mutex);//加锁

        printf("t2:thread id is:%ld\n",(unsigned long)pthread_self());
        printf("t2:is param:%d\n",*((int *)arg));

        pthread_mutex_unlock(&mutex);//解锁

}
void *func3(void *arg)
{
        pthread_mutex_lock(&mutex);//加锁

        printf("t3:thread id is:%ld\n",(unsigned long)pthread_self());
        printf("t3:is param:%d\n",*((int *)arg));

        pthread_mutex_unlock(&mutex);//解锁

}
int main()
{
        int ret;
        int param = 100;
        pthread_t t1;
        pthread_t t2;
        pthread_t t3;

        pthread_mutex_init(&mutex,NULL);//初始化锁

        ret = pthread_create(&t1,NULL,func1,(void *)¶m);//创建线程t1
        if(ret == 0){
                printf("main:创建线程t1成功!\n");
        }

        ret = pthread_create(&t2,NULL,func2,(void *)¶m);//创建线程t2
        if(ret == 0){
                printf("main:创建线程t2成功!\n");
        }

        ret = pthread_create(&t3,NULL,func3,(void *)¶m);//创建线程t3
        if(ret == 0){
                printf("main:创建线程t3成功!\n");
        }
        printf("main:获取主程序的ID:%ld\n",(unsigned long)pthread_self());


        pthread_join(t1,NULL);
        pthread_join(t2,NULL);
        pthread_join(t3,NULL);

        return 0;
}

结果:

Linux--线程--互斥锁_第1张图片

先拿到锁的是t1线程先运行,但是会和主线程争抢内存,因为主线程没加锁,虽然会被打断,但是对于其他t2,t3线程,他们只有等待阻塞,等t1先运行完

3.互斥锁限制共享内存的访问

#include
#include
#include 
#include
int data = 0;//定义一个全局变量data 
pthread_mutex_t mutex;

void *func1(void *arg)
{

        pthread_mutex_lock(&mutex);
        while(1){
                printf("线程t1拿到 data = %d\n",data++);
                sleep(1);
                if(data == 5){
                   printf("t1:data = %d\n",data);
                   pthread_mutex_unlock(&mutex);
                   printf("=========t1线程退出============\n");
                   exit(0);
                }
        }

}
void *func2(void *arg)
{

        while(1){
                printf("线程t2拿到 data = %d\n",data);
                pthread_mutex_lock(&mutex);
                data++;
                pthread_mutex_unlock(&mutex);
                sleep(1);
        }
}
int main()
{
        int ret;
        int param = 100;
        pthread_t t1;
        pthread_t t2;

        pthread_mutex_init(&mutex,NULL);
        ret = pthread_create(&t1,NULL,func1,(void *)¶m);//创建线程t1
        if(ret == 0){
                printf("main:创建线程t1成功!\n");
        }

        ret = pthread_create(&t2,NULL,func2,(void *)¶m);//创建线程t2
        if(ret == 0){
                printf("main:创建线程t2成功!\n");
        }


        printf("主线程main拿到data:%d\n",data);
        pthread_join(t1,NULL);
        pthread_join(t2,NULL);

        pthread_mutex_destroy(&mutex);
        
        return 0;
}

结果:

Linux--线程--互斥锁_第2张图片

t2解锁后,t1一直拿锁,知道循环结束,整个程序退出,因为是共享内存。

4.死锁

前提条件是定义了两把锁,其中一个线程拿到了第一把锁和第二把锁,另外的一个线程拿到了第二把锁和第一把锁,然后他们都在争用锁的使用权,因为都解他们各自拥有的第一把所,所以一直卡在争用锁锁的使用权。

代码:

#include 
#include 
 
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
pthread_mutex_t mutex;
pthread_mutex_t mutex2;
 
int g_data=0;
 
void *func1(void *arg)
{
	int i;
	pthread_mutex_lock(&mutex);
	sleep(1);
	pthread_mutex_lock(&mutex2);
 
	for(i=0;i<5;i++){
	printf("t1:%ld thread is create\n",(unsigned long)pthread_self());
	printf("t1:param is %d\n",*((int*)arg));
	sleep(1);
	}
 
	pthread_mutex_unlock(&mutex);
}
void *func2(void *arg)
{
        pthread_mutex_lock(&mutex2);
	sleep(1);
        pthread_mutex_lock(&mutex);
 
        printf("t2:%ld thread is create\n",(unsigned long)pthread_self());
        printf("t2:param is %d\n",*((int*)arg));
 
        pthread_mutex_unlock(&mutex);
 
}
 
 
int main()
{
	int ret;
	int param=100;
	pthread_t t1;
	pthread_t t2;
	
	pthread_mutex_init(&mutex,NULL);
	pthread_mutex_init(&mutex2,NULL);
 
	ret=pthread_create(&t1,NULL,func1,(void*)¶m);	
	if(ret==0){
		printf("main:create t1 success\n");
	}
        ret=pthread_create(&t2,NULL,func2,(void*)¶m);
        if(ret==0){
                printf("main:create t2 success\n");
        }
 
	
	printf("main %ld \n",(unsigned long)pthread_self());
 
	pthread_join(t1,NULL);
	pthread_join(t2,NULL);
 
	pthread_mutex_destroy(&mutex);
	pthread_mutex_destroy(&mutex2);
 
	return 0;
}

结果:

main:create t1 success
main:create t2 success
main 139666438145792 
^C
CLC@Embed_Learn:~/thread$ ./a.out
main:create t1 success
main:create t2 success
main 139839917381376 
^C
CLC@Embed_Learn:~/thread$ ./a.out
main:create t1 success
main:create t2 success
main 139912974800640 
^C
CLC@Embed_Learn:~/thread$ 

只有1把锁的情况下是不会造成死锁的

在这里func1拿着锁mutex,需要拿锁mutex2;func2拿着锁mutex2,需要拿锁mutex;从而造成了死锁。

你可能感兴趣的:(linux,c语言)