0
点赞
收藏
分享

微信扫一扫

线程,进程,开发板

zidea 2022-04-14 阅读 61
linux

一、线程

1、概述

线程是包含在进程内部顺序执行流,是进程中的实际运作单位,是操作系统能够进行调度基本单位。

2、创建线程

int pthread_create(
      	pthread_t *thread, 
		const pthread_attr_t *attr,
		void *(*start_routine)(void*),
	  	void *arg
); 

变量说明:

thread 指针指向新线程ID结构体;

attr 含有各种线程属性的属性对象;

start_routine 线程开始执行时调用的函数名;

arg 给start_routine函数提供参数,类型为void *.

返回值 成功返回0,否则返回错误码。

终止线程:

void pthread_exit(void *retval);

线程ID:

通过函数:my_tid = pthread_self( )
函数原型:pthread_t pthread_self(void)

比较相等:pthread_equal( )

运行结果如下:

线程连接与分离:

线程可以分为分离线程(DETACHED)和非分离线程(JOINABLE)两种:

连接:int pthread_join(pthread_t thread, void**retavl);

分离:int pthread_detach(pthread_t thread);

示例:

运行结果如下:

初始化与销毁:

基本的线程属性包括:栈大小、调度策略和状态属性。

初始化:int pthread_attr_init(pthread_attr_t *attr);

销毁:int pthread_attr_destroy(pthread_attr_t *attr);

示例:

 

 创建与销毁函数原型:

静态初始化
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
动态初始化
int pthread_mutex_init( );
销毁
int pthread_mutex_destroy( );
加锁
pthread_mutex_lock()
pthread_mutex_trylock()
解锁
pthread_mutex_unlock()


3、互斥量、互斥锁

临界区:必须以互斥方式执行的代码段,即在临界区的范围内只能有一个活动的执行线程。

互斥量(Mutex),又称为互斥锁,是用来保护临界区的特殊变量,每个互斥锁内部有一个线程等待队列,保存等待该互斥锁的线程。
有锁定(locked)和解锁(unlocked)状态:
锁定状态,某个特定的线程正持有这个互斥锁,其他线程将阻塞在互斥锁的等待队列内;
解锁状态,没有线程持有这个互斥锁,如果某个线程试图获取这个互斥锁,那么这个线程就可以得到这个互斥锁而不会阻塞。
示例:

效果:

 死锁:

结果:

条件变量:

互斥锁用来给资源上锁,而条件变量是用来等待而不是用来上锁。

条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。

 示例:

结果:

 二、进程

1、进程环境

程序:

程序是静态的,程序 = 指令序列(完成特地任务) + 数据

 进程:

是一个已经开始执行但还没有终止的程序实例。

包含有进程运行环境、内存地址空间、进程ID、和至少一个被称为线程的执行控制流等资源。

一个程序可以实例化为多个进程实体。

进程是一个动态的实体

程序到进程转换:

查找命令所对应程序文件的位置;

使用fork()函数为之创建一个新进程;

在新进程中调用exec族函数装载程序文件,并执行程序文件的main()函数。

进程的状态:
R:进程处于运行态或就绪状态,只有在该状态的进程才可能在CPU上运行;
D:不可中断的深睡眠状态,处于这种反状态的进程不能响应异步信号;
S:可中断的浅睡眠状态,处于这个状态的进程因为等待某种事件的发生而被挂起;
T:暂停状态或跟踪状态;
W:退出状态,进程即将被销毁;
Z:退出状态,进程成为僵尸进程。
 

进程的参数获取:
1、通过main()函数的第3个参数env获取

int main();

int main(int argc,char*argv[ ]);

int main(int argc,char*argv[ ],char*env[ ]);

agrc表示命令行参数的个数;argv是指向参数的各个指针所构成的数组,env参数是指向环境变量字符串的数组
2. 通过environ全局变量获取;
3. 通过getenv()函数获取。

进程环境示例:

2、基本操作:

创建进程:fork()

运行结果:

终止进程:

正常终止
调用类exit()函数。
main()函数return返回,也是调用类exit()函数

异常终止
调用abort()函数实现,通过SIGABRT信号调用

 被执行程序:负责打印参数个数、参数列表、变量环境。

wait()函数:

函数原型:pid_t wait(int *status)
status是用来保存子进程退出状态的指针。

帮助父进程获取其子进程的退出状态

如果父进程未调用wait()函数,则子进程的退出信息将一直保存在内存中

僵尸进程:子进程先终止,但父进程没有调用wait()一直占用系统资源。

孤儿进程:被init进程收官,由init进程负责收集它们的退出状态

示例:

结果:

守护进程:

后台运行的一种特殊进程,独立于控制终端,周期性地执行某种任务或等待处理某些事件

守护进程属于孤儿进程,父进程变为init进程

Linux系统的大多数服务器就是通过守护进程实现

常用daemon()创建守护进程

 原型:int daemon(int nochdir,int noclose);

示例:

3、系统信号

概念:

信号(signal),即软中断,用来通知进程发生了异步事件。是较为复杂的通信方式。

一般方向:进程之间、内核给进程。

仅通知事件类型,不传递数据。

进程处理信号方式:

忽略

系统默认(大部分的信号使得进程被终止)

类似中断,进程调用预先指定的、对应的函数

信号函数:

sigaction函数
改变信号的处理方法,SIGKILL和SIGSTO例外。

Kill()函数
向指定的进程发送一个指定的信号,成功返回0,否则返回-1。

 示例:

由于没有信号,因此一直在sleep,运行结果如下: 

 

 4、线程与进程的关系

一个线程只能是某一个进程的一部分,一个进程可以有多个线程(至少有一个主线程)

开发板:

$ ~/ubuntu-18.04_imx6ul_qemu_system/gui-qemu-imx6ull-gui.sh

1、LCD屏幕

打开:$ fb-test

$ ./myfb-test /dev/fb0

打开图像:

 

2、串口EEPROM

$ cd ~

$ i2cdetect -l #列出所有i2c总线

$ i2cdetect -y 0 #列出总线0上的设备 

 $ i2c_usr_test /dev/i2c-0 0x50 w 0x01 0xff #w = write

得到:

读取:$ i2c_usr_test /dev/i2c-0 0x50 w 0x33

读取0×33位置

 

3、命令控制LED

打开LED控制以及安装LED驱动:

$ cd ~

$ cd led_driver_qemu/

$ insmod 100ask_led.ko 

控制LED零号灯亮,LED一号灯灭:

$ ./ledtest /dev/100ask_led0 on

$ ./ledtest /dev/100ask_led1 off

 

4、按键控制LED

$ cd ~

$ cd button_driver_qemu/

$ insmod button_drv.ko

$ insmod board_100ask_qemu_imx6ull.ko  

启动按钮控制:

$ ./button_led_test

可以看到1号按钮控制灯亮了,2号按钮控制灯熄灭。

结束 

举报

相关推荐

线程 进程 开发板

多线程-进程-开发板

线程、进程与开发板

线程、进程和使用开发板

Linux的多线程进程开发板

多进程-进程-开发板

一起学习多线程、进程、开发板

arm开发板

开发板教程-20220404

0 条评论