多线程编程相关API

多线程编程

线程相关的基础概念
轻量级的进程
共享进程的资源
进程和线程的优缺点
启动线程比启动一个进程所花费的空间小 30倍
启动线程的时间 比启动进程的时间小
线程的切换速度要比进程的切换速度快 10倍左右
维护进程花费的内核资源比维护线程大
线程间通讯比进程间通讯更容易
线程的缺点 一死俱死
如何选择使用进程还是线程
1)需要频繁创建销毁 优先使用线程
2)需要大量的计算的时候 优先使用线程
3)强相关的时候优先线程 弱相关使用进程
4)多机用进程 多核线程
5)都满足 用最熟悉的

线程相关的函数

函数的功能:
创建一个线程 (重点)
函数的头文件
pthread.h
函数的原型
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
函数的参数
pthread_t *thread, 线程的id
const pthread_attr_t *attr, 线程的属性
分离属性 绑定属性
填NULL 使用默认属性
void *(*start_routine) (void *),:线程的回调函数
void *arg :传给回调函数的参数
函数的返回值:
成功返回 0
失败返回 非零
++++++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:
获取线程的id号
函数的头文件
pthread.h
函数的原型
pthread_t pthread_self(void);
函数的参数

函数的返回值:
返回线程的id号
+++++++++++++++++++++++++++++++++++++++++++++++++++++
由于线程相关的函数是放在外部库里的
所以在编译的时候 必须加上 -lpthread
+++++++++++++++++++++++++++++++++++++++++++++++++++++
线程的执行的特点
1)线程的执行是并发的
2)线程的执行的先后顺序是由cpu的调度算法决定的
++++++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:
退出线程的执行 exit
函数的头文件
pthread.h
函数的原型
void pthread_exit(void *retval);
函数的参数
void *retval:退出的状态
0 正常 其他的异常
函数的返回值:

++++++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:
等待指定的线程退出
函数的头文件
pthread.h
函数的原型
int pthread_join(pthread_t thread, void **retval);
函数的参数:
pthread_t thread, 要等待的线程
void **retval 保存退出的状态 一般填NULL
函数的返回值
成功返回 0
失败返回 错误码
+++++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:
取消指定的线程
函数的头文件
pthread.h
函数的原型
int pthread_cancel(pthread_t thread);
函数的参数
pthread_t thread:要取消的线程的id
函数的返回值
成功返回 0
失败返回 非零
++++++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:
退出清理
函数的头文件
pthread.h
函数的原型
void pthread_cleanup_push(void (*routine)(void *),void *arg);
void pthread_cleanup_pop(int execute);
函数的参数:
void (*routine)(void *):退出时执行的回调函数
void *arg :传给回调函数的参数
int execute:决定退出清理函数是否调用
0:表示不调用
1:表示调用
++++++++++++++++++++++++++++++++++++++++++++++++++++
# define pthread_cleanup_push(routine,arg)
{ struct _pthread_cleanup_buffer _buffer;
__pthread_cleanup_push (&_buffer, (routine), (arg));
extern void __pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
int execute) attribute_hidden;
# undef pthread_cleanup_pop
# define pthread_cleanup_pop(execute)
__pthread_cleanup_pop (&_buffer, (execute)); }
#endif
+++++++++++++++++++++++++++++++++++++++++++++++++++++
当退出清理函数两个宏之间假如有退出动作的时候
无论execute这个值是否为1 都会被调用
+++++++++++++++++++++++++++++++++++++++++++++++

线程的同步与互斥,相关API

1:为什么要有线程的同步与互斥
实现对临界资源的保护、独占
2:线程的同步与互斥的手段
互斥锁
条件变量
信号灯(类似与进程里的信号量)
3:互斥锁
锁:保护资源
互斥锁
本质上就是一个特殊的结构体
操作系统通过这个结构体模拟出一把锁
互斥锁主要就是用于线程里的资源的保护和独占
互斥锁是具有阻塞性
互斥锁的操作
加锁 解锁
互斥锁的死锁
互斥锁两次加锁
4:互斥锁相关的api
互斥锁的使用步骤
初始化锁
加锁
解锁
销毁锁
函数的功能:
初始化一个互斥锁
函数的头文件
#include
函数的原型
动态初始化
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
静态创建快速锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
函数的参数
pthread_mutex_t *restrict mutex,:互斥锁的核心结构体
只需要定义一个这样的结构体
取地址传进去即可
const pthread_mutexattr_t *restrict attr
锁的类型
NULL:
函数的返回值
成功返回 0
失败返回 非零
+++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:
互斥锁的加锁
函数的头文件
pthread.h
函数的原型
int pthread_mutex_lock(pthread_mutex_t *mutex);
阻塞的申请一个互斥锁 假如申请成功则返回 申请不成功则阻塞
int pthread_mutex_trylock(pthread_mutex_t *mutex);
非阻塞的申请一个互斥锁 无论申请成功还是不成功都马上返回
函数的参数:
pthread_mutex_t *mutex:互斥锁的核心结构体指针
函数的返回值:
成功返回 0
失败返回 非零
++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:
互斥锁的解锁
函数头文件
pthread.h
函数的原型
int pthread_mutex_unlock(pthread_mutex_t *mutex);
函数的参数:
pthread_mutex_t *mutex:互斥锁的核心结构体指针
函数的返回值
成功返回 0
失败返回 非零
+++++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:
销毁一个互斥锁
函数的头文件
pthread.h
函数的原型
int pthread_mutex_destroy(pthread_mutex_t *mutex);
函数的返回值
成功返回 0
失败返回 非零
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
5:条件变量
条件变量的作用与互斥锁的作用差不多
保护临界资源
条件变量的实现是依赖 互斥锁的
条件变量相关的api
静态创建条件变量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
函数的功能:
动态的创建条件变量
函数的头文件
pthread.h
函数的原型
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
函数的参数:
pthread_cond_t *restrict cond, 条件变量的核心结构体
const pthread_condattr_t *restrict attr :固定填NULL
函数的返回值
成功返回 0
失败返回 错误码
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:
阻塞线程
函数的头文件
pthread.h
函数的原型
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
函数的参数:
pthread_cond_t *restrict cond, 条件变量的核心结构体
pthread_mutex_t *restrict mutex 互斥锁的结构体
函数的返回值
成功返回 0
失败返回 非零
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:
解除阻塞
函数的头文件
pthread.h
函数的原型
int pthread_cond_signal(pthread_cond_t *cond);
函数的参数:
pthread_cond_t *cond:条件变量的核心结构体
函数的返回值
成功返回 0
失败返回 非零
++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:
销毁条件变量
函数的头文件
pthread.h
函数的原型
int pthread_cond_destroy(pthread_cond_t *cond);
函数的参数
pthread_cond_t *cond:条件变量的核心结构体
函数的返回值:
成功返回 0
失败返回 非零
++++++++++++++++++++++++++++++++++++++++++++++++++++
6:信号灯
本质上也是一个数字
这个数字可以进行加 也可以进行减
加的时候表示是释放信号
减的时候表示消耗信号
当数值是0的时候 表示信号已经被消耗完了不能再被消耗了
函数的功能:
创建信号灯
函数的头文件
#include
函数的原型
int sem_init(sem_t *sem, int pshared, unsigned int value);
函数的参数
sem_t *sem, 信号量的核心结构体
int pshared, 固定填 0
unsigned int value 信号量的初始值
函数的返回值
成功返回 0
失败返回 非零
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:
消耗信号量
函数的头文件
#include
函数的原型
int sem_wait(sem_t *sem);
阻塞的申请一个信号量 假如申请不到则阻塞
假如申请成功则返回
int sem_trywait(sem_t *sem);
非阻塞的申请一个信号量
无论申请成功与否都会马上返回
函数的参数
sem_t *sem:信号灯的核心结构体
函数的返回值
成功返回 0
失败返回 非零
+++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:
释放一个信号灯
函数的头文件
#include
函数的原型
int sem_post(sem_t *sem);
函数的参数
sem_t *sem:信号灯的核心结构体
函数的返回值
成功返回 0
失败返回 -1
++++++++++++++++++++++++++++++++++++++++++++++++++
函数的功能:
销毁信号灯
函数的头文件
#include
函数的原型
int sem_destroy(sem_t *sem);
函数的参数
sem_t *sem:信号灯的核心结构体
函数的返回值
成功返回 0
失败返回 -1
++++++++++++++++++++++++++++++++++++++++++++++++++++
线程间的通讯
1)全局变量
2)特定函数
函数的功能:
给某个线程发送某个特定的信号
函数的头文件
#include
函数的原型
int pthread_kill(pthread_t thread, int sig);
函数的参数
pthread_t thread, 线程的id
int sig 要发送的信号
函数的返回值
成功返回 0
失败返回 错误码

你可能感兴趣的:(C语言,c语言,linux)