轻量级进程,本质仍然是进程,都是通过clone函数实现的。
进程:独立的地址空间,拥有PCB,最小的资源分配单元
线程:没有独立的地址空间,拥有PCB,最小的执行单元
优点:提高并发性、占用资源小、通信方便
缺点:库函数不稳定、编写和调试困难、对信号支持不好
#include
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
功能:创建线程
函数参数:
注:编译需要添加pthread库
#include
pthread_t pthread_self(void);
功能:返回调用函数的ID,这个值与调用pthread_create返回的pthread_t *thread一样。
#include
void pthread_exit(void *retval);
功能:终止调用的进程函数
函数参数:
pthread_exit和return的区别:
#include
int pthread_join(pthread_t thread, void **retval);
功能:获取某个线程执行结束时返回的数据,pthread_join会一直阻塞调用它的线程,接收到目标线程的返回值,阻塞状态才会解除。
参数:
注:一个线程执行结束的返回值只能由一个 pthread_join() 函数获取,当有多个线程调用 pthread_join() 函数获取同一个线程的执行结果时,哪个线程最先执行 pthread_join() 函数,执行结果就由那个线程获得,其它线程的 pthread_join() 函数都将执行失败。
创建线程demo
#include
#include
#include
void *thr(void *args)
{
printf("Im a thread, pid = %d, tid = %u.\n", getpid(), pthread_self());
sleep(5);
return (void*)0;
}
int main()
{
pthread_t tid;
pthread_create(&tid, nullptr, thr, nullptr);
printf("Im main, pid = %d, tid = %u.\n", getpid(), pthread_self());
int ret = 0;
if ((ret = pthread_join(tid, nullptr)) > 0) { // 阻塞等待线程回收
printf("join err : %d, %s\n", ret, strerror(ret));
}
printf("I will exit.\n");
pthread_exit(nullptr);
return 0;
}
线程退出注意事项:
#include
int pthread_detach(pthread_t thread);
功能:线程分离,线程主动与主线程断开关系,线程结束之后,其退出状态不由其他线程获取,而是自己直接自动释放,网络、多线程服务常用。pthread有两种状态joinable状态和unjoinable状态,一个线程默认的状态是joinable。如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当调用了pthread_join之后这些资源才会被释放。若是
unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己, 如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。如果线程状态为 joinable,需要在之后适时调用pthread_join。
参数:
pthread_t thread:
注:不能对一个已经分离的线程调用pthread_join,这样的调用将返回EINVAL错误。也就是说,一个线程调用了pthread_detach就不能再调用pthread_join。
线程分离函数demo:
#include
#include
#include
#include
void *thr(void *args)
{
printf("Im a thread, pid = %d, tid = %u.\n", getpid(), pthread_self());
sleep(5);
return (void*)0;
}
int main()
{
pthread_t tid;
pthread_create(&tid, nullptr, thr, nullptr);
printf("Im main, pid = %d, tid = %u.\n", getpid(), pthread_self());
pthread_detach(tid); // 线程分离
sleep(5);
int ret = 0;
if ((ret = pthread_join(tid, nullptr)) > 0) {
printf("join err : %d, %s\n", ret, strerror(ret));
}
printf("I will exit.\n");
pthread_exit(nullptr);
return 0;
}
pthread_join函数阻塞等待回收失败
Im main, pid = 525576, tid = 3930953536.
Im a thread, pid = 525576, tid = 3922568960.
join err : 22, Invalid argument
I will exit.
#include
int pthread_cancel(pthread_t thread);
功能:仅仅是向目标线程发送 Cancel 信号,至于目标线程是否处理该信号以及何时结束执行,由目标线程决定。对于接收 Cancel 信号后结束执行的目标线程,等同于该线程自己执行pthread_exit(PTHREAD_CANCELED)。也就是说,当一个线程被强制终止执行时,它会返回 PTHREAD_CANCELED 。因此,当对一个cancel的进程进行pthrean_join回收时,得到的返回值为-1
参数:
杀死线程函数demo:
#include
#include
#include
#include
void *thr(void *args)
{
while(1) {
printf("Im a thread, pid = %d, tid = %u.\n", getpid(), pthread_self());
sleep(1);
}
return (void*)0;
}
int main()
{
pthread_t tid;
pthread_create(&tid, nullptr, thr, nullptr);
printf("Im main, pid = %d, tid = %u.\n", getpid(), pthread_self());
sleep(5);
pthread_cancel(tid);
void *ret;
ret = pthread_join(tid, &ret);
printf("thread exit with : %d\n", (int)ret);
return 0;
}
#include
int pthread_attr_init(pthread_attr_t *attr); // 初始化线程属性
int pthread_attr_destroy(pthread_attr_t *attr); // 销毁线程属性
// 设置属性分离态
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
功能: 设置属性分离状态
参数:
设置线程属性demo
#include
#include
#include
#include
void *thr(void *arg)
{
printf("I am a thread.\n");
return NULL;
}
int main(int argc, char *argv[])
{
pthread_attr_t attr;
pthread_attr_init(&attr); // 初始化属性
pthread_attr_getdetachstate(&arr, PTHREAD_CREATE_DETACHED); //设置属性分离
pthread_t tid;
pthread_create(&tid, &attr, thr, NULL);
int ret = 0;
if ((ret = pthread_join(tid, NULL)) > 0) {
printf("join err: %d, %s\n", ret, strerror(ret));
}
pthread_attr_destroy(&attr);
}
其他: