文章目录
线程概念(了解)
进程
- 进程有独立 的地址空间
- linux为每隔进程穿件task_struct
- 每个进程都参与内核调度,互不影响
线程 - 进程在切换时系统开销大
- 很多操作系统引入了轻量级进程LWP
- 同一进程中的线程共享相同地址空间
- linux不区分进程、线程
线程特点(了解)
-
通常线程指的是共享相同地址空间的多个任务
-
使用多个线程的好处
大大提高了任务切换的效率
避免额外的TLB&cache的刷新 -
线程共享资源
可执行的命令
静态数据
进程中打开的文件描述符
当前工作目录
用户ID
用户组 ID -
线程私有资源
线程ID(TID)
PC和相关寄存器
堆栈
错误号
优先级
执行状态和属性
线程创建(熟练)
创建pthread_create
#include <pthread.h>
int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void*(*routine)(void*),void *arg);
//成功返回0,失败返回错误码
//thread线程对象
//attr线程属性,NULL代表默认属性
//routine线程执行的函数,线程创建的时候,会执行该函数
//arg传递给routine的参数
删除pthread_join
#include <pthread.h>
int pthread_join(pthread_t thread,void **retval);
//成功返回0,失败返回错误码
//thread要回收的线程对象
//调用线程阻塞直到thread结束
//*retval接收线程thread的返回值
结束pthread_exit
#include <pthread.h>
void pthread_exit(void *retval);
//结束当前线程
//retval可被其它线程通过pthread_join获取(不能是局部变量)
//线程私有资源被释放
线程 e.g.
char message[32] = "Hello Worle";
void *thread_func(void *arg);
void *thread_func(void *arg){
sleep(1);
strcpy(message,"marked by thread");
pthread_exit("thank you for waiting for me");
}
int main(void){
pthread_t a_thread;
void *result;
if(pthread_create(&a_thread,NULL,&thread_func,NULL) != 0){
printf("fail to pthread_create");
exit(-1);
}
pthread_join(a_thread,&result);
printf("result is %s\n",result);
printf("message is %s\n",message);
return 0;
}
$gcc -o test test.c -lpthread //添加链接选项-l
$./test
thank you for waiting for me
marked by thread
线程通信
同步-POSIX信号量
-
POSIX定义的两类信号量
无名信号量(基于内存的信号量):一般用于线程间通信
有名信号量,可用于进程或线程间通信 -
pthread库常用的信号量操作函数:
int sem_init(sem_t *sem,int pshared,unsigned int value);
int sem_wait(sem_t *sem);//P操作
int sem_post(sem_t *sem);//V操作
#include <semaphore.h>
int sem_init(sem_t *sem,int pshared,unsigned int val);
//success return 0 ,faile return EOF
//sem point to semaphore handle
//pshared 0 for thread ,1 for process
//val 信号量初值
e.g.
//生产者和消费者
char buf[32];
sem_t sem;
void *funtion(void *arg);
int main(void){
pthread_t a_thread;
if(sem_init(&sem,0,0) < 0){//信号量初始值为0,没有资源
perror("sem_init");
exit(-1);
}
if(pthread_create(&a_thread,NULL,function,NULL) != 0){
printf("fail to pthread_create");
exit(-1);
}
printf("input 'quit' to exit\n");
do{
fgets(buf,32,stdin);
sem_post(&sem);
}while(srtncmp(buf,"quit",4) != 0);
return 0;
}
void *function(void *arg){
while(1){
sem_wait(&sem);
printf("you enter %d characters\n",strlen(buf));
}
}
ps aux -L |grep sem //查看线程状态
互斥
- 临界资源
包括数组、全局变量等全局缓存,不能多线程同时访问
一次只允许一个任务(进程、线程)访问的共享资源 - 临界区
访问临界区的代码 - 互斥机制
mutex互斥锁
任务访问临界资源前申请锁,访问完之后释放锁
互斥锁初始化-pthread_mutex_init
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
//成功返回0,失败返回错误码
//mutex指向要初始化的互斥锁对象
//如果无法获得锁,任务阻塞
释放锁-pthread_mutex_unlock
#jinclude <pthread.h>
int pthread_mutex_unlock(pthread_mutex_t *mutex);
//success 0 failed error code
//mutex
//执行完临界区要及时释放锁
L5-D3