嵌入式学习---DAY26:线程---锁

一、线程结束方式

1.pthread_exit()

2.main函数中的return

3.pthread_cancel   线程的取消

#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>

void * do_something(void *arg)
{
	static int a = 10;
	while (1)
	{
		printf("------do_something ---- \n");
        sleep(1);
	}
	return &a;
}

int main(int argc, const char *argv[])
{
	pthread_t tid;
	int ret = pthread_create(&tid,NULL,do_something,NULL);

	if (ret != 0)
	{
		errno = ret;
		perror("pthread_create fail");
		return -1;
	}

	sleep(3);

	pthread_cancel(tid);

	printf("----cancel thread----\n");

	pthread_exit(NULL);

	return 0;
}

4.任何一个线程调用exit,或主函数结束return都会造成进程结束。

pthread_cancel(pthread_t thread)

参数表示tid码。

功能:发送取消的请求     成功返回0,失败返回错误码

  二、线程资源回收 

函数:pthread_detach(); 

int pthread_detach(pthread_t thread);

功能:分离线程 

参数:thread 要分离的线程的tid
返回值:成功 0,失败 错误码 

pthread_join    //需要自己回收  ---线程的属性 (可结合性)  --- 一般是子线程 在较短时间内运行完 

这种用于 ,线程任务较短,主线程需要关心子线程状态 

pthread_detach  //可分离属性    ---子线程运行很久才结束 ---  设置分离属性,子程序执行任务较长,主线程也不需要关心子线程状态

#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>

void * do_something(void *arg)
{
	static int a = 10;
	//线程的任务函数 
	printf("------do_something ---- \n");

	//pthread_exit(NULL);
	pthread_exit(&a);
	//pthread_exit((void *)a);
}

int main(int argc, const char *argv[])
{
	pthread_t tid;
	int ret = pthread_create(&tid,NULL,do_something,NULL);
	if (ret != 0)
	{
		errno = ret;
		perror("pthread_create fail");
		return -1;
	}
    pthread_detach(tid);

	void *retval; 
	if (pthread_join(tid,&retval)  != 0)
	{
		perror("pthread_join fail");
		return -1;
	}


	printf("---- main----%d\n",*(int *)retval);

	//pthread_exit(NULL);

	return 0;
}

三、锁

 共享资源:    临界资源

临界区  :    访问共享资源(临界资源)那段代码 

互斥锁:互斥     排他性   --- 要么不访问 要访问就是一次完整操作  (原子操作)

定义互斥锁 ==》初始化锁 ==》加锁 ==》解锁 ==》销毁

定义互斥锁:pthread_mutex_t   mutex; 

初始化锁:pthread_mutex_init();

加锁:pthread_mutex_lock(); 

解锁 :pthread_mutex_unlock(); 

销毁:pthread_mutex_destroy();

 pthread_mutex_init()    

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

参数:mutex     //就是要初始化的 互斥锁变量 

            attr      //属性  NULL 默认属性  --- 普通锁 ,读写锁 

int pthread_mutex_lock(pthread_mutex_t *mutex);     上锁

int pthread_mutex_trylock(pthread_mutex_t *mutex);   尝试获取锁,

int pthread_mutex_unlock(pthread_mutex_t *mutex);   解锁

参数:mutex    //要操作的那把锁 

int pthread_mutex_destroy(pthread_mutex_t *mutex); //用完之后锁要销毁 

锁是一种线程间 同步机制 

互斥锁 -- 保证线程对于共享资源的排他性访问 。 保证每个线程访问时的原子性操作 

操作 :初始化 一把锁 (动态初始化 pthread_mutex_init,静态初始化 用初始化的宏)---加锁---解锁---销毁。

#include <head.h>


//静态初始化 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
char buf[20];

void * doSth1(void *arg)
{
	while (1)
	{
		pthread_mutex_lock(&mutex);
		int i = 0;
		for (i = 0; i < 10; ++i)
		{
			buf[i] = 'a' + i;
		}
		printf("Sth1 buf = %s\n",buf);
		pthread_mutex_unlock(&mutex);
	}
}

void * doSth2(void *arg)
{
	while (1)
	{
		pthread_mutex_lock(&mutex);
		int i = 0;
		for (i = 0; i < 10; ++i)
		{
			buf[i] = '0' + i;
		}
		printf("Sth2 buf = %s\n",buf);
		pthread_mutex_unlock(&mutex);
	}
}


int main(int argc, const char *argv[])
{
	pthread_t tid[2];

	int ret = pthread_create(&tid[0],NULL,doSth1,NULL);
	if (ret != 0)
		handle_error_en(ret,"pthread_create fail");	
	ret = pthread_create(&tid[1],NULL,doSth2,NULL);
	if (ret != 0)
		handle_error_en(ret,"pthread_create fail");	

	pthread_join(tid[0],NULL);
	pthread_join(tid[1],NULL);

	pthread_mutex_destroy(&mutex);
	
	return 0;
}

 四、死锁

1.什么是死锁

死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象。

当多个进程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前

进,这种情况就是死锁。

很显然,如果没有外力的作用,那么死锁涉及到的各个进程都将永远处于封锁状态。

2.死锁产生的四个必要条件:四者缺一不可,均需满足

(1)互斥条件:进程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。

(2)不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的进程自己来释放(只能是主动释放)。

(3)请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。

(4)循环等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被链中下一个进程所请求。注:发生死锁一定有循环等待,但是循环等待不一定是死锁。

3.死锁的处理策略

(1)预防死锁。破坏死锁产生的四个必要条件中的一个或几个,

(2)避免死锁。用某种方法防止系统进入不安全状态,从而避免死锁(银行家算法)

(3)死锁的检测和解除。允许死锁的发生,不过操作系统会负责检测出死锁的发生,然后采取某种措施解除死锁。

4.什么时候会发生死锁

(1)对系统资源的竞争。各进程对不可剥夺的资源(如打印机)的竞争可能引起死锁,对可剥夺的资源(CPU)的竞争是不会引起死锁的。

(2)进程推进顺序非法。请求和释放资源的顺序不当,也同样会导致死锁。例如,并发执行的进程P1P2分别申请并占有了资源 R1、R2,之后进程P1又紧接着申请资源R2,而进程P2又申请资源R1,两者会因为申请的资源被对方占有而阻塞,从而发生死锁。

(3)信号量的使用不当也会造成死锁。如生产者-消费者问题中,如果实现互斥的P操作在实现同步的P操作之前,就有可能导致死锁。(可以把互斥信号量、同步信号量也看做是一种抽象的系统资源)
总之,对不可剥夺资源的不合理分配,可能导致死锁。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值