Linux--线程--互斥锁

这篇具有很好参考价值的文章主要介绍了Linux--线程--互斥锁。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

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

include <pthread.h>
// 返回:若成功返回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<stdio.h>
#include<pthread.h>
#include <unistd.h>

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 *)&param);//创建线程t1
        if(ret == 0){
                printf("main:创建线程t1成功!\n");
        }

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

        ret = pthread_create(&t3,NULL,func3,(void *)&param);//创建线程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--线程--互斥锁,linux,c语言

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

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

#include<stdio.h>
#include<pthread.h>
#include <unistd.h>
#include<stdlib.h>
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 *)&param);//创建线程t1
        if(ret == 0){
                printf("main:创建线程t1成功!\n");
        }

        ret = pthread_create(&t2,NULL,func2,(void *)&param);//创建线程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--线程--互斥锁,linux,c语言

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

4.死锁

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

代码:

#include <stdio.h>
#include <pthread.h>
 
//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*)&param);	
	if(ret==0){
		printf("main:create t1 success\n");
	}
        ret=pthread_create(&t2,NULL,func2,(void*)&param);
        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;从而造成了死锁。文章来源地址https://www.toymoban.com/news/detail-738405.html

到了这里,关于Linux--线程--互斥锁的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux--线程--互斥锁

    1.互斥量 a)互斥量(mutex)从本质上来说是一把锁,一般在主线程中定义一个互斥量,就是定义一把锁。然后根据我们的需求来对线程操作这把锁。 b)如果给所有的线程都加上锁了,线程们会去争取内存空间,谁先争取到谁先运行,直到该线程解锁后,期间其他线程只能等

    2024年02月06日
    浏览(41)
  • 【linux】线程互斥

    喜欢的点赞,收藏,关注一下把! 到目前为止我们学了线程概念,线程控制接下来我们进行下一个话题,线程互斥。 有没有考虑过这样的一个问题,既然 线程一旦被创建,几乎所有资源都是被所有线程共享的。 那多个线程访问同一份共享资源有没有什么问题? 下面我们模

    2024年02月03日
    浏览(38)
  • linux:线程互斥

    个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》《C++》《Linux》 本文是对于线程互斥的知识总结 我们先看下面代码。 该代码创建三个线程-1,线程-2,线程-3,去抢夺ticket资源,当ticket从10000依次减到0时,三个线程退出。那该代码运行结果是什么呢?ticket最后会是

    2024年03月21日
    浏览(38)
  • Linux->线程互斥

    前言: 1 线程互斥 1.1 多线程并发问题 1.2 线程锁 1.3 锁的接口 2 线程安全与可重入函数  3 死锁         本篇文章主要讲解了线程互斥的实现方式,还有原理,并附上代码讲解。并且讲解了锁的概念,问题等。         还记得我上一篇文章的结尾有提过的问题吗?如果多个

    2024年02月10日
    浏览(38)
  • Linux多线程互斥锁

    迷途小书童的 Note 读完需要 5 分钟 速读仅需 2 分钟 1 引言 在 Linux 编程中,多线程是一种常见的并发编程模型。为了保证多线程之间的数据同步和互斥访问,pthread_mutex(互斥锁)是一个重要的工具。本文将深入探讨 pthread_mutex 的底层实现原理、函数原型,并提供详细的使用方

    2024年02月10日
    浏览(52)
  • Linux之线程互斥

    目录 一、问题引入 二、线程互斥 1、相关概念 2、加锁保护 1、静态分配 2、动态分配 3、锁的原理 4、死锁 三、可重入与线程安全 1、概念 2、常见的线程不安全的情况 3、常见的线程安全的情况 4、常见不可重入的情况 5、常见可重入的情况 6、可重入与线程安全联系 7、可重

    2024年03月16日
    浏览(87)
  • 【关于Linux中----线程互斥】

    先来用代码模拟一个抢票的场景,四个线程不停地抢票,一共有1000张票,抢完为止,代码如下: 执行结果如下: 可以看到,最后出现了票数为负数的情况,很显然这是错误的,是不应该出现的。 为什么会出现这种情况? 首先要明确,上述的几个线程是不能同时执行抢票的

    2023年04月19日
    浏览(71)
  • 【Linux】多线程互斥与同步

    互斥 指的是一种机制,用于确保在同一时刻只有一个进程或线程能够访问共享资源或执行临界区代码。 互斥的目的是 防止多个并发执行的进程或线程访问共享资源时产生竞争条件,从而保证数据的一致性和正确性 ,下面我们来使用多线程来模拟实现一个抢票的场景,看看所

    2024年02月09日
    浏览(38)
  • Linux——多线程,互斥与同步

    目录 一.linux互斥 1.进程线程间的互斥相关背景概念 2.互斥量mutex 3.加锁互斥锁mutex 4.锁的底层原理  二.可重入VS线程安全 1.概念 2.常见的线程不安全的情况 3.常见的线程安全的情况  4.常见不可重入的情况  5..常见可重入的情况 6.可重入与线程安全联系  三.死锁 1.死锁四个必

    2024年02月05日
    浏览(33)
  • Linux——线程的同步与互斥

    目录 模拟抢火车票的过程 代码示例 thread.cc Thread.hpp 运行结果 分析原因 tickets减到-2的本质  解决抢票出错的方案 临界资源的概念 原子性的概念 加锁 定义 初始化 销毁 代码形式如下 代码示例1: 代码示例2: 总结 如何看待锁 申请失败将会阻塞  pthread_mutex_tyrlock 互斥锁实现

    2024年02月06日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包