嵌入式学习DAY28 --- 线程、同步和互斥问题、如何实现同步和互斥?

本文深入探讨嵌入式系统中的线程概念,包括线程的定义、特性、创建与销毁,以及多线程共享资源和线程私有资源。同时,介绍了同步和互斥的重要性,详细讲解了同步机制如信号量和无名信号量的使用,以及互斥锁的实现。通过实例代码展示了如何在实践中应用这些概念解决并发访问临界资源的问题。

嵌入式入门学习笔记,遇到的问题以及心得体会!
DAY28


概述:

一、线程
二、同步和互斥问题
三、如何实现同步
四、如何实现互斥


笔记:

一、线程

1、什么是线程:

(1)线程是轻量级的进程

(2)线程存在于进程内,不能独立存在

(3)线程参与CPU调度,进程是系统资源分配最小单位,线程是系统调度的最小单位

(4)在单核CPU中,多线程并发属于伪并发,但是不牵扯虚拟地址空间的切换,所以开销比进程间切换要小很多

(5)在多核CPU中,多线程可以实现真并发

前面我们已经提到,进程是系统中程序执行和资源分配的基本单位每个进程都拥有自己的数据段,代码段和堆
栈段,这就造成了进程在进行切换时,操作系统的开销比较大。
为了提高效率,操作系统又引入了另一个概念——线程,也称轻量级的进程。线程可以对进程的内存空间和资源进行访问,并与同一进程中的其他线程共享。因此,线程的上下文切换的开销比进程小得多。
一个进程可以拥有多个线程,其中每一个线程共享该进程所拥有的资源。要注意的是,由于线程共享了进程的资源和地址空间,因此,任何线程对于系统资源的操作都会给其他线程带来影响。由此可知,多线程中的同步是非常重要的问题。在多线程系统中,进程与线程的关系图如下:

在这里插入图片描述

2、哪些是多线程共享的资源,哪些是线程私有的资源:

线程(Thread):有时候被称为轻量级进程(Lightweight Process, LWP),是程序执行流的最小单元。一个标准的线程由线程ID、当前指令指针(PC)、寄存器集合和堆栈组成。

通常一个进程由一个到多个线程组成,各个线程之间共享程序的内存空间(包括代码段、数据段、堆等)以及一些进成级的资源(如打开文件和信号)。一个经典的线程与进程的关系图如下:

	|---------------------------------------------------|
	|代码		|数据		|进程空间	|打开文件		|
	|---------------------------------------------------|
	|													|
	|	|-----------|	|-----------|	|-----------|	|
	|	|寄存器		|	|寄存器		|	|寄存器		|	|
	|	|-----------|	|-----------|	|-----------|	|
	|	|栈			|	|栈			|	|栈			|	|
	|	|-----------|	|-----------|	|-----------|	|
	|	|			|	|			|	|			|	|
	|	|			|	|			|	|			|	|
	|	|			|	|			|	|			|	|
	|	|			|	|			|	|			|	|
	|	|			|	|			|	|			|	|
	|	|			|	|			|	|			|	|
	|	|MainThread	|	|Thread1	|	|Thread2	|	|
	|	|-----------|	|-----------|	|-----------|	|
	|													|
	|		进程的地址空间使用分配图						|
	|---------------------------------------------------|

3、使用多线程的原因:

<1>某个操作可能会陷入长时间等待,等待的线程会进入睡眠状态,无法继续执行。多线程执行可以有效利用等待的时间。典型的例子是等待网络响应。这可能要花费数秒甚至数十秒。

<2>某个操作(常常是计算)会消耗大量的时间,如果只有一个线程,程序和用户之间的交互会中断。多线程可以让一个线程负责交互,另一个线程负责计算。

<3>程序逻辑本身要求并发操作,例如一个多端下载软件(Bittorrent)

<4>多CPU或多核计算机,本身具备同时执行多个线程的能力,因此单线程程序无法全面地发挥计算机地全部计算能力。

<5>相对于多进程应用程序,多线程在数据共享方面效率要高很多。

4、线程地访问权限:

线程地访问非常自由,它可以访问进程内存里的所有数据,甚至包括其他线程的堆栈(如果它知道其他线程的堆栈地址,那么这就是很少见的情况),但实际运用中线程也拥有自己的私有存储空间,包括以下几个方面:
<1>栈:尽管并非完全无法被其他线程访问,但一般情况下仍然可以认为是私有的。
<2>线程局部存储(Thread Local Storage, TLS):线程局部存储是某些操作系统为线程单独提供的私有空间,但通常只具有很有限的容量。
<3>寄存器(包括PC寄存器):寄存器是执行流的基本数据,因此为线程私有。

从C程序员的角度来分析,数据在线程之间是否私有如下表:
|-----------------------|-----------------------------------------------|
|线程私有				|线程之间共享(进程所有)							|
|-----------------------|-----------------------------------------------|
|局部变量				|全局变量										|
|函数的参数				|堆上的数据										|
|TLS数据				|函数里的静态变量								|
|						|程序代码,任何线程都有权利读取并执行任何代码	    |
|						|打开的文件,A线程打开的文件可以由B线程读写		|	
|-----------------------|-----------------------------------------------|

在这里插入图片描述

5、如何创建线程:

pthread_create()

头文件:
#include <pthread.h>
		
			/*
			 *函数名:pthread_create
			 *函数功能:创建一个线程
			 *函数参数:
			 *			pthread_t *thread:
			 *			const pthread_attr_t *attr:创建线程时的参数的指针
			 *			void *(*start_routine) (void *):线程处理函数的指针
			 *			void *arg:线程处理函数的参数
			 *函数返回值:int:成功返回0,失败返回非零
			 */
			int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

注意:Compile and link with -pthread. 编译时加-lpthread

6、如何让线程执行特定任务:

通过线程处理函数来实现

7、线程的释放:

(1)pthread_detach
头文件:
#include <pthread.h>
		/*
		 *函数名:pthread_detach
		 *函数功能:销毁一个线程
		 *函数的参数:
		 *			pthread_t thread:要销毁的线程
		 *函数返回值:int:成功反回0,失败错误码
		 */
		int pthread_detach(pthread_t thread);
(2)pthread_join
头文件:
#include <pthread.h>
		/*
		 *函数名:pthread_join
		 *函数功能:等待线程的退出
		 *函数参数:
		 *			pthread_t thread:要等待的线程
		 *			void **retval:线程的退出状态
		 *函数返回值:int:成功反回0,失败错误码
		 */
		int pthread_join(pthread_t thread, void **retval);
(3)pthread_exit
(4)pthread_cancel

8.线程代码演示

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

void *t1f(void *arg)
{
   
   
	while(1)
	{
   
   
		printf("Tom and Jerry!\n");
	}
	return NULL;
}

void *t2f(void *arg)
{
   
   
	while(1)
	{
   
   
		printf("Tomats\n");
	}
	return NULL;
}

int main()
{
   
   
评论 9
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值