线程是进程内的一条执行路径或执行序列; 一个进程可以包含多条线程
用户级:
创建开销小,由线程库直接管理, 无法使用多处理器资源
内核级:
创建开销大,由内核直接管理, 可以使用多处理器资源
组合模型:
既可以使用多处理器资源,又能创建多个
头文件:#include <pthread.h>
1.创建线程
#include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void*(*start_routine)(void*), void *arg);
pthread_create(); 用于创建线程
thread:用于接收创建的线程的ID
attr:指定线程的属性;多为NULL
start_routine: 指定线程函数
arg: 给线程函数传递的参数; 成功返回0,错误返回错误码
2.退出线程
int pthread_exit(void* retval); //退出线程
pthread_exit(); 退出线程
retval: 指定退出信息
3.等待线程退出
int pthread_join(pthread_t thread, void ** retal);
pthread_join() 等待thread指定的线程退出,线程未退出时该方法阻塞
retal : 接收thread线程退出时,指定的退出信息
线程同步是指当一个线程在对临界资源进行操作时,其他线程都不可以对该资源进行操作,直到该线程完成操作,其他线程才能操作,也就是协同步调,让线程按照预定先后次序执行。
线程同步的四种方法:互斥锁、信号量、条件变量、读写锁
1、概念: 用于保护关键代码段,确保在任一时刻只能有一个线程访问该资源,既保证在该时刻内其独占式的访问
2.互斥锁的基本API
以下这些函数成功时返回0,失败则返回错误码
#include<pthread.h> int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* mutexattr);
PS: 也可以这样初始化互斥锁(静态化初始锁):
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
宏PTHREAD_MUTEX_INITIALIZER 实际上只是把互斥锁的各个字段都初始化为0
int pthread_mutex_lock(pthread_mutex_t* mutex);
int pthread_mutex_unlock(pthread_mutex_t* mutex);
int pthread_mutex_destory(pthread_mutex_t* mutex);
以下这些函数成功时返回0,失败则返回-1并设置errno
#include<semaphore.h> int sem_init(sem_t* sem, int pshared, unsigned int value);
int sem_wait(sem_t* sem);
int sem_post(sem_t* sem);
int sem_destory(sem_t* sem);
条件变量提供了一种线程间的通知机制;当某个共享数据达到某个值的时候,唤醒等待这个共享数据的线程
(成功返回0; 失败返回错误码)
int pthread_cond_init(pthread_cond_t* cond, pthread_conattr_t* cond_attr);
int pthread_cond_signal(pthread_cond_t* cond);
int pthread_cond_broadcast(pthread_cond_t* cond);
int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex);
细化——锁; 分“读锁”、“写锁”
未加锁 读加锁 写加锁 读锁 Yes Yes No 写锁 Yes No No
成功返回0; 失败返回错误码
int pthread_rwlock_init(pthread_rwlock_t*rwlock, pthread_rwlockattr_t* attr);
int pthread_rwlock_rdlock(pthread_rwlock_t* rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t* rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t* rwlock);
int pthread_rwlock_t_destory(pthread_rwlock_t* rwlock);
多线程中无论调度顺序如何,最终的结果都是一样的、正确的。那么说这些线程是安全的
要点: