Linux--线程的控制与分离

一、线程的概念

线程是进程内部的一个基本执行流,是系统调度的一个实体。进程具有独占性,线程具有共享性。各线程共享进程的文件描述符、信号处理的方式、当前的工作目录、用户id(uid)和组id(gid)。但是有些资源线程是私有的,比如线程id、栈空间、上下文(包括各种寄存器的值。程序计数器和栈指针)、占空间、信号屏蔽字、调度优先级。就好比进程如果是一个家庭的话,线程就是这个家庭的成员,每个家庭的成员都有一个公共的空间(餐厅,客厅)。当然每个家庭成员也有自己的私人空间了。

二、线程的控制

创建线程和终止

用函数pthread_create()创建,成功返回0,失败返归错误号。调用 pthread_create()创建新的线程后。当前线程从pthread_create()返回继续往下执行。新的线程所执行的代码由函数指针start_routine决定。函数start_routine函数接收一个参数,是通过pthread_create()的arg传给它的。类型为void*,start_toutine的返回值类型也是void*,start_toutine返回后,这个线程就退出了,其他线程可以调用pthread_join()得到start_toutine的返回值。start_toutine函数可以通过①return(void*)、②pthread_exit(void*)、③pthread_cancel(pthread_self())三种终止。

  1 #include<stdio.h>
  2 #include<pthread.h>
  3 void * thread_run(void* arg)
  4 {
  5     int count=5;
  6     while(1)
  7     {
  8         printf("this is a thread,thread id is\n"pthread_self());
  9         sleep(1);
 10     }
 11     //return (void*)1;
 12     //pthread_exit((void*)2);
 13     // pthread_cancel(pthread_self());
 14 }
 15 int main()
 16 {
 17     pthread_t id;
 18     int ret=pthread_create(&id,NULL,thread_run,NULL);
 19     int count=10;
 20     while(count-->0)
 21     {
 22         printf("this is a main thread,thread id is %u\n",pthread_self());
 23         sleep(1);
 24     }
 25     void * ted=0;
 26     pthread_cancel(id);
 27     pthread_join(id,&ted);
 28     printf("return success %d\n",(int)ted);
 29 }

可以看出:

1、如果通过return返回。pthread_join接收的值是线程的返回值

2、如果线程被别的线程调用pthread_cancel异常终止掉。则返回错误码

3、如果是调用pthread_exit终止的。pthread_join存放的是传给pthread_exit的参数。

4、两个线程的线程号是不一样的

三、线程分离

线程在任一个时间点上。是可结合的(joinable)或者是可分离的(detached)。可结合的线程可被其他的线程回收资源和杀死。在被其他线程回收之前,它的存储器资源是不释放的。而可分离的线程是不能被其他回收或杀死的,它的存储器资源在它终止时由系统自动释放。默认情况下。线程被创建成可结合的。为了避免内存泄漏,每个可结合的线程都应该要么被显示的回收,即调用pthread_join;要么通过pthread_detach函数分离。

如果如果一个可结合线程结束运行但没有被pthread_join,则它的状态类似于进程中的僵尸进程,即还有一部分资源没有被回收,所以创建线程者应该调用pthread_join来等待线程运行结束,并可得到线程的退出代码,回收其资源。调用pthread_join后,如果该线程没有运行结束,调用者会被阻塞。这是可以在子线程中加入代码pthread_detach(pthread_self())或者父线程调用pthread_detach(thread_id)非阻塞,可立即返回。这将该子线程的状态设置为分离的(detached),如此一来,该线程运行结束后会自动释放所有资源。

  1 #include<stdio.h>
  2 #include<pthread.h>
  3 void* thread_run(void* arg)
  4 {
  5     pthread_detach(pthread_self()); //分离线程
  6     printf("this is a thrad \n");
  7     return (void*)1;
  8 }
  9 int main()
 10 {
 11     pthread_t id;
 12     int ret= pthread_create(&id,NULL,thread_run,NULL);
 13     printf("this is a main thread\n");
 14     sleep(1);
 15 
 16     int res=pthread_join(id,NULL);
 17     if(res==0)
 18     {
 19         printf("pthrad wait succced\n");
 20         return 0;
 21     }
 22     else
 23     {
 24         printf("pthread wait faile\n");
 25         return 1;
 26     }
 27     return 0;
 28 }

如果把子线程中的pthread_detach(pthread_self())注释掉,则结果如下,这是因为把子线程中分离去掉后,其他线程就可以对子线程进程join和杀死,然后释放掉存储器资源。而上面是因为在子进程中已经分离的,所以其他线程不能在对其访问了,join返回fail

总结:

线程的控制从创建线程-->子线程的三种终止方式-->其他线程join线程。终止的方式不同,join的返回值就不同。线程的分离,如果子线程中加入pthread_detach()就把子线程设置成了可分离的线程,线程退出后会自动释放存储器资源,不会造成内存泄漏。如果不设置的话,就要用join显示接收,然后释放资源,也不会造成内存泄漏。

时间: 2024-07-29 23:41:41

Linux--线程的控制与分离的相关文章

线程的控制与分离

线程的控制 线程的创建: 线程创建函数:int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(*start_routine(void*),void *arg); 返回值:成功返回0,失败返回错误号. 在一个线程中调用pthread_create()创建新的线程后,当前线程从pthread_create()返回继续往下执行,而新的线程所执行的代码由我们传给pthread_create()的函数指针star_ro

Linux - 线程属性控制

线程属性 属性值不能直接设置,须使用相关函数进行操作 初始化函数为pthread_attr_init,该函数必须在pthread_create函数之前调用 typedef struct{ int detachstate; // 线程的分离状态 int scope; // 线程绑定状态 int schedpolicy; // 线程调度策略 struct sched_param schedparam; // 线程的调度参数 int inheritsched; //线程的继承性 size_t guar

Linux之线程:控制与分离

之前我一直都提到的是进程,现在多了一个线程的概念,从字面意思来看,线程应该比进程小.嘿嘿. 其实操作系统刚开始的时候,提出进程概念后,操作系统一直都是以进程作为独立运行的基本单位,然后有人感觉了,这不对呀,进程之间的中断转换太浪费了,并且用户态到核心态的切换也有点麻烦,所以在80年代中期,人们又提出了毕竟更小的独立运行的基本单位咯--线程,用来提高系统内存程序的并发执行程度.所以线程就这么出现了. 那,什么是线程呢? 其实简单来说,线程就是进程中的执行分流,从操作系统内部来说其实就是一个指令序列

Linux下线程的控制与分离

一.线程的概念: 线程是运行在进程地址空间的,是进程的执行分流.它是执行进程内部的一个代码片段为了让进程更好的完成.也可以说,进程是承担系统资源的实体,而线程进程运行调度的基本单位. 由于同一进程的多个线程共享同一地址空间,因此Text Segment.Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个全局变量,在各线程中都可以访问到,除此之外,各线程还共享以下进程资源和环境: 1. 文件描述符表 2. 每种信号的处理方式(SIG_IGN.SIG_DFL或者

线程的控制和分离

线程的概念:线程是运行在进程内的一个基本执行流,和进程共享地址空间及资源(类似于父子进程共享地址空间),但每个也有自己的私有资源. 进程强调独占性 每个进程都有它独立的地址空间,包括Text Segment.Data Segment等 线程强调共享性 线程的共享资源: 1.进程代码段 2.进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯) 3.进程打开的文件描述符 4.信号的处理器 5.进程的当前目录和进程用户ID与进程组ID 线程的私有资源:(线程实现并发性)       1

使用信号量控制Linux线程同步

线程同步 在现实生活中,有些东西就必须是按顺序执行的,只有我完成了以后,你才能在我的劳动成果上接着干:不能我还没有完成,你就开始干活了.这就是线程同步最直白的解释了. 在进行程序设计时,亦是如此.线程同步,同步的是什么?它同步的是对共享资源(内存区域,公共变量等)或者临界区域的访问.有的时候,这些共享 资源和临界区域,就只能容忍一个线程对它进行操作(读或者写,读操作一般不控制,主要是写操作),这个时候,我们必须要对这些共享资源或者临界区域进行同 步,那么如何对它们进行线程同步呢? 在Linux中

Linux 线程与进程,以及通信

http://blog.chinaunix.net/uid-25324849-id-3110075.html 部分转自:http://blog.chinaunix.net/uid-20620288-id-3025213.html 1.首先要明确进程和线程的含义: 进程(Process)是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位.与程序相比,程序只是一组指令的有序集合,它本身没有任何运行的含义,只是一个静态实体.进程是程序在某个数据集上的执行,

Linux线程编程之信号处理

前言 Linux多线程环境中的信号处理不同于进程的信号处理.一方面线程间信号处理函数的共享性使得信号处理更为复杂,另一方面普通异步信号又可转换为同步方式来简化处理. 本文首先介绍信号处理在进程中和线程间的不同,然后描述相应的线程库函数,在此基础上给出一组示例代码,以讨论线程编程中信号处理的细节和注意事项.文中涉及的代码运行环境如下: 本文通过sigwait()调用来“等待”信号,而通过signal()/sigaction()注册的信号处理函数来“捕获”信号,以体现其同步和异步的区别. 一  概念

linux 线程详解

线程 是计算机中独立运行的最小单位,运行时占用很少的系统资源.可以把线程看成是操作系统分配CPU时间的基本单元.一个进程可以拥有一个至多个线程.它线程在进程内部共享地址空间.打开的文件描述符等资源.同时线程也有其私有的数据信息,包括:线程号.寄存器(程序计数器和堆栈指针).堆栈.信号掩码.优先级.线程私有存储空间. 为什么有了进程的概念后,还要再引入线程呢?使用多线程到底有哪些好处?什么的系统应该选用多线程?我们首先必须回答这些问题. 使用多线程的理由之一是和进程相比,它是一种非常"节俭&quo

Linux线程学习(二)

一.Linux进程与线程概述 进程与线程 为什么对于大多数合作性任务,多线程比多个独立的进程更优越呢?这是因为,线程共享相同的内存空间.不同的线程可以存取内存中的同一个变量.所以,程序中的所有线程都可以读或写声明过的全局变量.如果曾用fork() 编写过重要代码,就会认识到这个工具的重要性.为什么呢?虽然fork() 允许创建多个进程,但它还会带来以下通信问题:如何让多个进程相互通信,这里每个进程都有各自独立的内存空间.对这个问题没有一个简单的答案.虽然有许多不同种类的本地IPC (进程间通信)