多线程
1.线程(thread):
是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。
2.安装pthread库:
- ubuntu默认没有pthread库,需要安装。
$ sudo apt-get install -y glibc-doc manpages-posix-dev
3.线程的创建与终止。
4.线程的终止
void pthread_exit(void*_retval)
5.线程的连接
int pthread_join(
pthread_t tid, //需要等待的线程,指定的线程必须位于当前的进程中,而且不得是分离线程
void **status //线程tid所执行的函数返回值(返回值地址需要保证有效),其中status可以为NULL
);
6.线程管理
- 线程初始化
int pthread_attr_init(pthread_attr_t *attr);
- 线程销毁
int pthread_attr_destroy(pthread_attr_t *attr);
7.互斥量,互斥锁 Mutex
- 什么是互斥量
临界区:必须以互斥方式执行的代码段,即在临界区的范围内只能有一个活动的执行线程。
互斥量(Mutex),又称为互斥锁,是用来保护临界区的特殊变量,每个互斥锁内部有一个线程等待队列,保存等待该互斥锁的线程。
有锁定(locked)和解锁(unlocked)状态:
锁定状态,某个特定的线程正持有这个互斥锁,其他线程将阻塞在互斥锁的等待队列内;
解锁状态,没有线程持有这个互斥锁,如果某个线程试图获取这个互斥锁,那么这个线程就可以得到这个互斥锁而不会阻塞。
- 使用互斥量前要先初始化,也就是上面线程管理的内容。
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
- 对互斥量进行加锁和解锁的函数:
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
-
死锁
- 互斥锁加锁与解锁
互斥锁可用来保护多个线程共享的数据和结构不会被他人修改,一个互斥锁只能有两个状态,即加锁和解锁状态,所用到pthread_mutex_lock()和pthread_mutex_unlock()函数。加锁可使其不被其他线程访问,只能由一个线程掌握,解锁即解除加锁的互斥锁,而这所用到的代码如下:
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
-
条件变量
进程
1.何为程序
程序是静态的
程序 = 指令序列(完成特地任务) + 数据
2.何为进程
狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。
广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
3.进程的状态
R:进程处于运行态或就绪状态,只有在该状态的进程才可能在CPU上运行;
D:不可中断的深睡眠状态,处于这种反状态的进程不能响应异步信号;
S:可中断的浅睡眠状态,处于这个状态的进程因为等待某种事件的发生而被挂起;
T:暂停状态或跟踪状态;
W:退出状态,进程即将被销毁;
Z:退出状态,进程成为僵尸进程。
4.获取环境变量
-
进程的参数
环境变量
进程获取环境变量的3种途径:
1)通过main()函数的第3个参数env获取;
Main ()函数的三种原型:
- int main();
- int main(int argc, char *argvO);
- int main(int argc, char *argv[], char *env);
argc表明命令行参数的个数;argv是指向参数的各个指针所构成的数组, env参数是指向环境变量字符串的数组
2)通过environ全局变量获取;
3)通过getenv()函数获取。
5.创建进程
- 函数以拷贝父进程的方式创建子进程。子进程与父进程有相同的代码空间、文件描述符等资源
- 创建后,子进程与父进程开始并发执行,执行顺序由内核调度算法来决定
- fork()对父子进程各返回一次,
父进程:子进程的PID,
子进程:0;
失败: 小于0;
开发板
$ ~/ubuntu-18.04_imx6ul_qemu_system/gui-qemu-imx6ull-gui.sh
先打开开发板,再打开LCD图像和屏幕:
$ fb-test
$ cd myfb-test
$ ./myfb-test /dev/fb0
串口EEPROM
$ cd
$ i2cdetect -l #列出所有ic2总线
$ i2cdetect -y 0 #列出总线0上的设备
UU:有设备,有内核驱动
地址:有设备,无驱动
命令控制LED
打开LED控制、安装LED驱动:
$ cd
$ cd led_driver_qemu/
$ insmod 100ask_led.ko
控制LED零号灯亮,控制LED灯一号灯灭:
$ ./ledtest /dev/100ask_led0 on
$ ./ledtest /dev/100ask_led1 off
按键控制LED
安装驱动:
$ cd
$ cd button_driver_qemu/
$ insmod button_drv.ko #扫描你的按键
$ insmod board_100ask_qemu_imx6ull.ko
启动按键控制:
$ ./button_led_test
之后你就可以通过虚拟的按键来控制LED灯的亮灭了。