Linux--进程与线程的互斥详解

一、进程的互斥与同步

  见本人另外一篇博客链接: 进程互斥与同步讲解.

二、Linux多线程编程—互斥量的讲解

  在多线程的编程当中,如果需要访问共同的资源比如同类型的变量等。这同样也是需要我们对变量进行保护。使用pthread的互斥接口来实现互斥变量的访问,[互斥量]mutex本质来说就是一把锁,拿到锁的人才能打开门,才能进入到我们的临界资源中去访问临界资源。没有锁的人就得在外面处于堵塞状态,只到里面的人出来,外面的人才能开始争资源,谁先拿到锁,谁就能先进去访问临界资源。
  在操作系统中,只有将线程做成相同数据机制访问,才能实现数据的互斥访问。操作系统并不会为我们做数据的访问的串行化,如果没有统一的规则,在访问规则的时候就会产生混乱。
  在线程当中外面用pthread_mutex_t来定义锁的类型,如果是静态分配的数据量,需要用pthread_mutex_init来初始化锁,如果是动态分配互斥量,在释放内存的时侯需要调用pthread_mutex_destroy进行互斥量的销毁。

三、Linux多线程编程函数API

  如何创建线程这里就不详细讲解了见链接: 线程讲解.
1.pthread_mutex_init(),初始化锁

int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr)

2.pthread_mutex_destroy(),销毁一个锁

int pthread_mutex_destroy(pthread_mutex_t* mutex)

3.pthread_mutex_lock(),加锁

int pthread_mutex_lock(pthread_mutex_t* mutex)

4.pthread_mutex_unlock(),解锁

int pthread_mutex_unlock(pthread_mutex_t* mutex)

6.下面是函数的具体使用:

#include<stdio.h>
#include<string.h>
#include <pthread.h>

int data = 0;				//共享数据

pthread_mutex_t mutex;		//互斥量

void *fun1(void *arg)
{
	printf("xianchen1:the xiancheng num is %ld\n",(unsigned long)pthread_self());//序列号
	printf("xianchen1:the parm is %d\n",*((int *)arg));	//parm的值
	 	
	pthread_mutex_lock(&mutex);							//加锁

	while(1)
	{
		sleep(1);
		printf("xianchen:the data is %d \n",++data);
		if(data==4)
		{
			printf("fun1 quit!************\n");		//如果等于四就退出
			pthread_mutex_unlock(&mutex);			//退出后解锁
			pthread_exit(NULL);
		}
	}
}

void *fun2(void *arg)
{
	
	printf("xianchen2:the xiancheng2 num is %ld \n",(unsigned long)pthread_self());
        printf("xianchen2:the parm is %d\n",*((int *)arg));
        while(1)
	{
		pthread_mutex_lock(&mutex);//加锁
       	printf("xianchen2:the data is %d\n",data++);
		pthread_mutex_unlock(&mutex);//解锁
		sleep(1);
	}
	pthread_exit(NULL);
}

int main()
{
	
	pthread_t t1;
	pthread_t t2;
	int gram = 100;
	//int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
	int ret;
	int ret2;

	pthread_mutex_init(&mutex,NULL);	

	ret = pthread_create(&t1,NULL,fun1,(void *)&gram);
  	ret2 = pthread_create(&t2,NULL,fun2,(void *)&gram);

	char *ptrs = NULL;	
	char *ptrs2 = NULL;

	if (ret==0)
	{
		printf("main: printf xaincheng sucess!\n");
	}
	while(1)
	{
		printf("main:%d\n",data);
		sleep(1);
	}

	pthread_join(t1,(void **)&ptrs);
    pthread_join(t2,(void **)&ptrs2);
	
	pthread_mutex_destroy(&mutex);
	return 0;
}

7.测试结果
在这里插入图片描述
  我们编程的目的达到了,就是要让线程二中的data的值加到4然后退出,让主线程和线程一去争夺资源。达到目的,实现了加锁和解锁。

四、死锁以及如何避免死锁

  4.1死锁的原因
  死锁是在多个线程的情况下,系统资源能够提供的资源个数比请求该资源的进程数要少,当系统中的的多个进程因申请资源得不到满足而等待时,线程都没有能力进行下一步执行,就会出现冲突造成死锁。

  4.2解决死锁策略
1.采用静态资源分配方法预防死锁,即在应用程序即将进入到系统时进行,通过预先分批资源,每一个用户向系统提起资源求情,若系统能满足该请求则同意调入主存。
2.采用动态资源分配,有效避免的方法。通过动态资源分配能合理利用资源,但是会发生死锁,所以就需要一些检测算法进行检测避免产生死锁。
3.忽略死锁,在UNIX操作系统中,若发生死锁直接重启系统。避免了检测算法占用资源。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值