本文共 2351 字,大约阅读时间需要 7 分钟。
线程是进程内部的一个执行分支(执行流),一个进程至少有一条main线(第一个PCB),也可以包含多条线程。
多个线程在同一个地址空间运行,共用同一虚拟空间,共用部分资源。
linux下并没有真正意义上的线程存在,linux中使用进程来模拟实现线程,父进程创建子进程,子进程执行父进程的一部分代码,并且 与父进程共享同一个地址空间。这些一个一个被创建出来的子进程可看到为线程,这种线程也称之为轻量级进程。
每个线程只有一个独自的栈结构,栈区空间。.data .bss .heap 等空间都是同一个进程共用的。
1.优点:
线程占用的资源比进程少,只虚复制PCB即可,创建时代价较小
线程间的切换(调度)需要操作系统做的工作少很多
线程间共享数据更容易
在等待慢速 I/O操作结束的同时,程序可执行其他的计算任务。
计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现。
I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。2.缺点:
性能损失
健壮性降低(由于线程是共享同一块虚拟地址空间的,在运行期间,因时间分
缺乏访问控制(当在线程中调用某些函数(OS函数,处理signal函数,调用kill/exit函数),可能会导致线程退出,从而使所有的线程都异常退出);编程难度提高(线程共用同一块虚拟地址空间,势必在处理多线程时会有访问同一个资源等问题,此时就涉及到共享资源的处理)
1. 用户级线程 2. 内核级线程 3. 混合级线程
**
1.创建线程:创建出新线程后,新线程去执行函数,主线程继续往下运行,谁先谁后不一定。
#includeint pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); //参数: //thread:线程id,将线程id存入,线程标识符,线程栈的起始地址,输出型参数 //attr:线程属性,NULL,8种选项 //函数指针:新线程执行该函数指针指向的代码,线程回调函数 //arg:传递给函数指针指向的函数的参数,线程回调函数的参数 //返回值:成功返回0,失败返回错误码,如: //EAGAIN 描述: 超出了系统限制,如创建的线程太多。 //EINVAL 描述: tattr 的值无效。
#include#include #include #include #include void *test(void *arg){ int i=0; while(i<5) { printf("test\n"); i++; sleep(1); }}int main(){ pthread_t tid; int res=pthread_create(&tid,NULL,test,NULL); assert(res==0); int i=0; while(i<5) { printf("main\n"); i++; sleep(1); }}
#include//等待线程结束的方法int pthread_join (pthread_t thread, //要等待的线程ID void **result);//用于接收线程退出的退出码
功能:以阻塞的方式回收新线程,可以得到线程的退出码,并回收其资源
如果不使用pthread_join回收线程,有可能造成和僵尸进程一样的问题,造成内存泄漏3.终止线程
main方法结束会默认调用exit,一旦某个线程调用exit所有线程也就结束了,所以需要使用线程库方法来控制线程结束。
#include//结束线程的方法int pthread_exit(*result);
只是当前线程结束,不影响其他线程。
4.分离线程
#includeint pthread_detach(pthread_t thread); //将pthread_thread对应的线程设为分离态的线程 //新线程中写:pthread_detach(pthread_self()); //主线程中写:pthread_detach(thread);
线程分为两种状态:可结合态和分离态;默认情况下,线程被创建成可结合的。
可结合态:
这种状态下的线程是能够被其他进程回收其资源或杀死的,这句话我的理解是:与其说它能够被其他进程回收或杀死,不如说它需要被其他进程回收或杀死;当它在被其他线程回收之前,它的存储器资源(如栈)是不会释放的;
这跟子进程很相似,如果不用父进程wait回收的话,就会变成僵尸进程同理,如果一个可结合态线程不用pthread_join回收,则会变成类似僵尸进程分离态:
这种状态下的线程是不能够被其他线程回收或杀死的;它的存储资源在它终止时由系统自动释放
为了避免存储器泄漏,每个可结合线程需要显示的调用pthread_join回收;要么就将其变成分离态的线程转载地址:http://xklg.baihongyu.com/