注:本文是听韦东山老师课程后的个人笔记,详细内容可以看韦东山老师的课程网站,这个部分课程是免费的。
一、多线程编程的意义
嵌入式系统中会出现很多不同的但需要实时检测的功能,
例如:播放器,既要按键扫描,又要播放音乐。
如果使用多进程,即两个main函数,相互交互,效率低,进程资源不共享,切换慢,但资源封闭,安全性高。
使用多线程解决这个问题,就会很合适,效率高
(资源分配以进程为单位,调度以线程为单位)
二、多线程编程需要的函数
1、创造线程的函数
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
Compile and link with -pthread.
2、同步操作
初始化
#include <semaphore.h>
int sem_init(sem_t *sem,int pshared,unsigned int value);
等待/释放:
#include <pthread.h>
int sem_wait(sem_t *sem);
int sem_post(sem_t *sem);
3、互斥访问
如果在线程1访问公共变量是,线程2把变量改变,那么就会数据出错,因此需要互斥锁。
需要以下函数:
static pthread_mutex_t g_tMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&g_tMutex);
pthread_mutex_unlock(&g_tMutex);
可能问题:因为fgets一直再度stdin的操作,导致互斥锁一直被一个线程占用。其他线程如果有互斥锁则无法调用
pthread_mutex_lock(&g_tMutex);
fgets(g_buf,1000,stdin);
pthread_mutex_unlock(&g_tMutex);
改进方法:
fgets(g_buf,1000,stdin);
pthread_mutex_lock(&g_tMutex);
memcpy(g_buf,buf,1000);
pthread_mutex_unlock(&g_tMutex);
4、条件变量(与互斥量同时使用)
需要以下函数
static pthread_cond_t g_tConVar = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t g_tMutex = PTHREAD_MUTEX_INITIALIZER;
线程A: 等待条件成立,
条件变量会先获得互斥量,如果满足条件执行后面代码,不成立,释放互斥量。
pthread_mutex_lock(&g_tMutex);
pthread_cond_wait(&g_tConVar, &g_tMutex);
/* 操作临界资源 */
pthread_mutex_unlock(&g_tMutex);
线程B: 唤醒等待g_tConVar的线程
条件成立的唤醒函数,一般存在另一个线程中
pthread_cond_signal(&g_tConVar);
5、其他基本操作
- 如果后台运行,要加&字符
./pthread &
- 查看进程 ps, 查看线程 ps -T
ps
ps -T
- 查看线程具体参数(进程同理)
cd /proc/线程号
cd /proc/线程号/task
- top命令,查看不同进程的资源占用情况(类似win里面的任务管理器中的资源占用窗口)
三、debug记录
1
undefined reference to `pthread_create'
collect2: error: ld returned 1 exit status
要加入线程的连接库
gcc -o pthread pthread.c -lpthread
2
pthread_create成功创建的返回值是0,所以做判断的时候要认真读取man手册。