线程概念:线程是在进程内部运行的(也就是在进程的地址空间内运行的),是进程的一个执行分支。
线程与进程的区别:
- Linux下线程是在进程的地址空间内运行的,线程拥有进程的一部分资源与代码,是进程的一个执行分支
- 线程是cpu的基本调度单位
- 进程是承担资源分配的基本单位
- Linux下进程被称为轻量级进程
- Linux下无真正意义的线程,线程是用进程模拟实现的
线程之间有共享的资源:
文件描述符表、信号的处理、当前工作目录、用户id和组id
线程各自也有私有的资源:
上下文信息(保存各种寄存器的值,和一些上下文的信息)、
私有栈空间、线程id、errno变量、信号屏蔽字、调度优先级
创建线程:
使用 int pthread_creat(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
参数描述:
thread:线程id,是一个输出型的参数
attr:线程属性,在创建时为NULL
strat_routine:创建线程要去执行的代码部分
arg:要传递给执行代码部分的参数
返回值:
成功返回0,出错返回错误码
注意:普通线程运行完成后要进行回收,不然会产生类似于僵尸进程的状态,从而造成内存泄漏,所以主线程必须等待其他线程,对其进行回收。
线程等待:
使用 int pthread_join(pthread_t thread, void **retval);
//当一个线程在运行中出错时,整个进程会挂掉,因为一个线程出错,操作系统会向发送信号结束其生命,但是操作系统是向pid发送信号,从而导致进程挂掉,进而导致所有线程挂掉。
参数描述:
thread:线程id
retval:输出型参数,用来获取线程的退出码
返回值:
成功返回0,失败返回对应的错误码
注意:线程要是一直没有退出,主线程便会一直等待,这种等待方式称为阻塞式等待。
线程终止:
线程终止有三种情况:
①正常return;
②void pthread_exit(void *retval);//用于终止线程,类似于进程使用exit()
③int pthread_cancel(pthread_t thread);//线程是可以被取消的,这个函数使一个线程结束掉同一进程的其他线程
成功返回0, 失败返回其错误码。
注意:在线程中调用exit()会导致进程整体的结束。
线程分离:
线程有两种状态,一种为可结合的,一种为分离的,一般默认下线程是可结合的。
上面说过,一个线程没有退出,主线程便一直等待其运行结束,对其资源进行回收,这种状态就称为可结合的。
但是一个线程要是被设置为分离的,那么主线程便不会在去等待回收那个线程,这个线程运行结束时会由操作系统对其进行资源回收,而且
一个分离线程是不能被其他线程所结束掉的。
注意:当一个进程结束时,其有一个分离的线程还未结束,那么其将会被强制结束,因为线程的资源都是进程分配给它的,而进程结束时其资源会被操作系统回收,此时线程会被结束掉。
当一个线程被设置为分离时,就不能被等待。
测试代码:
#include<stdio.h>
#include<pthread.h>
int i = 0;
void *pthread1(void *arg)
{
while(1)
{
sleep(1);
printf("线程一:running\n");
if(i++ > 5)
{
printf("线程一退出\n");
break;
}
}
}
void *pthread2(void *arg)
{
while(1)
{
sleep(2);
printf("线程二:running\n");
}
}
void *pthread3(void *arg)
{
while(3)
{
sleep(2);
printf("线程三:running\n");
}
}
int main()
{
pthread_t thread1;
pthread_t thread2;
pthread_t thread3;
pthread_create(&thread1, NULL, pthread1, NULL);
pthread_create(&thread2, NULL, pthread2, NULL);
pthread_create(&thread3, NULL, pthread3, NULL);
pthread_join(thread1, NULL); //线程1,设置为被等待
if(0 == pthread_cancel(thread2))//线程2,被主线取消,一旦运行在这块,线程2就结束了
{
printf("线程二被主线程取消\n");
}
if(0 == pthread_detach(thread3)) //线程3,被主线程设置为可分离状态
{
printf("线程三被主线程设置为可分离状态\n");
}
sleep(3);//在睡眠的3秒中,只有线程3在运行
}
运行结果:
zhi