多线程
创建子线程函数
# include <pthread.h>
int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, void *(*start_rtn)(void*), void *arg);
参数:tidp ==》 指向线程标识符的指针。
attr ==》 用来设置线程属性,设置非阻塞见下
start_rtn ==》 线程执行函数
arg ==》 运行子线程函数的参数
返回:0代表成功
发送终止信号函数(被动结束)
作用:发送终止信号给 tid 线程
#include <pthread.h>
int pthread_cancel(pthread_t thread);
参数:tid ==》 需要终止线程的 id
返回:成功 0 失败 it returns a nonzero error number
通常和pthread_join函数一起使用
注意:函数调用成功不是意味着线程马上终止,如果线程是 joinable 状态的话,那么,结束不会释放内存资源。参考学习僵尸线程和僵尸进程等概念
等待线程的结束
pthread_join(pid, NULL);
可解决僵尸线程,但是会造成阻塞
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
int pthread_join(pthread_t thread) //???
参数 :thread: ==》 线程标识符,即线程ID,标识唯一线程。
retval ==》 用户定义的指针,用来存储被等待线程的返回值。不使用设置NULL
返回:成功 0
线程主动结束
通过调用pthread_exit函数终止执行
void pthread_exit(void* retval);
文件读写:
FILE *source;
source = fopen(file, “rb”);
fread(buf, 1, buflen, source);
fwrite(“hello”, 1, 5, source);
fclose(source);
设置线程非阻塞结束
int pthread_detach(pthread_t thread);
参数:thread ==》 线程号,线程内可以使用 pthread_self() 返回值获取
使用以下属性设置创建线程可以使线程非阻塞结束:
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
设置线程 cancel 响应
#include <pthread.h>
int pthread_setcancelstate(int state, int *oldstate);
int pthread_setcanceltype(int type, int *oldtype);
编译添加链接: -pthread
参数:state ==》 PTHREAD_CANCEL_ENABLE 可以响应 pthread_cancel 函数
PTHREAD_CANCEL_DISABLE 不响应 pthread_cancel 函数
oldstate ==》 使用函数变换state之前的state
参数:type ==》 PTHREAD_CANCEL_DEFERRED 默认,目标线程并不会马上取消,而是在执行下一条cancellation point的时候才会取消
PTHREAD_CANCEL_ASYNCHRONOUS 内核收到取消,目标线程会立即调度内核取消(无法保证是立即取消)
oldtype ==》 使用函数变换type之前的type
线程清理
线程被 cancel 所有清理函数都被执行
#include <pthread.h>
void pthread_cleanup_push(void (*routine)(void *), void *arg);
void pthread_cleanup_pop(int execute);
参数:routine ==》 清理函数的函数名
arg ==》 清理函数参数
参数:execute ==》 执行清理函数的个数,按照 push 和 pop 顺序取execute个函数执行