3线程的终止方式,线程属性,NPTL



1线程终止方式

如果需要只终止某个线程而不终止整个线程,可以有三种方法:

A:从主线程函数return.这种方法对主线程不适合,从main函数return相当于调用exit.

B:一个线程可以调用pthread_cancel终止同一进程中的另一个线程。

C:线程可以调用pthread_exit终止自己

 

同一个进程的线程间,pthread_cancel向另一个线程发终止信号。系统不会马上关闭被取消线程,只有在被取消线程下次系统调用时,才会真正结束线程。或调用pthread_testcancel,让内核去检测是否需要取消当前线程。

 

2.线程属性

   Linux下线程的属性是可以根据实际项目需要,进行设置,可以改变线程的默认属性,默认属性已经可以解决大多数开发时遇到的问题。如我们对程序的性能提出更高的要求,那么需要设置线程属性,比如可以通过设置线程栈的大小来降低内存的使用,增加最大线程个数。

typedef struct

{

int etachstate;              //线程的分离状态

int schedpolicy;             //线程调度策略

structsched_param schedparam; //线程的调度参数

int inheritsched;             //线程的继承性

int scope;                  //线程的作用域

size_t guardsize;             //线程栈末尾的警戒缓冲区大小

int stackaddr_set;            //线程的栈设置

void* stackaddr;             //线程栈的位置

size_t stacksize;              //线程栈的大小

}pthread_attr_t;

上面是一个简写的结构体,用来设置线程的信息

 

属性值不能直接设置,须使用相关函数进行操作,初始化的函数为pthread_attr_init,

这个函数必须在pthread_create函数之前调用。之后须用pthread_attr_destroy函数来释

放资源。线程属性主要包括如下属性:作用域(scope)、栈尺寸(stack
size)、栈地址

(stack address)、优先级(priority)、分离的状态(detached
state)、调度策略和

参数(scheduling policy and parameters)。默认的属性为非绑定、非分离、缺省M的堆

栈、与父进程同样级别的优先级。

 

2线程属性初始化

先初始化线程属性,再pthread_create创建线程

A依赖的头文件

#include<pthread.h>

B函数声明

int pthread_attr_init(pthread_attr_t*attr);   //初始化线程属性

int pthread_attr_destroy(pthread_attr_t*attr); //销毁线程属性所占用的资源

 

案例说明:

运行结果:

总结:之所以会出现Invalid argument是因为分离后又调用了pthread_join

3线程的分离状态(detachedstate)

A线程的分离状态决定一个线程以什么样的方式来终止自己。

B非分离状态:线程的默认属性是非分离状态,这种情况下,原有的线程等待创建的线程结束。只有当pthread_join()函数返回时,创建的线程才算终止,才能释放自己占用的系统资源

C分离状态:分离线程没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源。应该根据自己的需要,选择适当的分离状态。

 

线程分离状态的函数:

#include <pthread.h>

intpthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); //设置线程属性,分离or非分离

intpthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate); //获取程属性,分离or非分离

pthread_attr_t *attr:被已初始化的线程属性

int *detachstate:可选为PTHREAD_CREATE_DETACHED(分离线程)和PTHREAD_CREATE_JOINABLE(非分离线程)

 

注意:如果设置一个线程为分离线程,而这个线程运行又非常快,它很可能在pthread_create函数返回之前就终止了,它终止以后就可能将线程号和系统资源移交给其他的线程使用,这样调用pthread_create的线程就得到了错误的线程号。要避免这种情况可以采取一定的同步措施,最简单的方法之一是可以在被创建的线程里调用pthread_cond_timedwait函数,让这个线程等待一会儿,留出足够的时间让函数pthread_create返回。设置一段等待时间,是在多线程编程里常用的方法。但是注意不要使用诸如wait()之类的函数,它们是使整个进程睡眠,并不能解决线程同步的问题。

 

4线程的栈地址(stack address)

   POSIX.1定义了两个常量_POSIX_THREAD_ATTR_STACKADDR和_POSIX_THREAD_ATTR_STACKSIZE检测系统是否支持栈属性。也可以给sysconf函数传递_SC_THREAD_ATTR_STACKADDR或_SC_THREAD_ATTR_STACKSIZE来进行检测。

当进程栈地址空间不够用时,指定新建线程使用由malloc分配的空间作为自己的栈空

间。通过pthread_attr_setstackaddr和pthread_attr_getstackaddr两个函数分别设置和获

取线程的栈地址。传给pthread_attr_setstackaddr函数的地址是缓冲区的低地址(不一定

是栈的开始地址,栈可能从高地址往低地址增长)。

#include<pthread.h>

函数声明

intpthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr);

intpthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr);

 

attr:指向一个线程属性的指针

stackaddr:返回获取的栈地址

返回值:若是成功返回0,否则返回错误的编号

说明:函数已过时,一般用下面讲到的pthread_attr_getstack来代替

 

案例说明

运行结果:

 

5 NPTL

查看当前pthread库版本

  getconfGNU_LIBPTHREAD_VERSION

  

  NPTL实现机制(POSIX),Native
POSIX Thread Library

  使用线程库时gcc指定-lpthread

 

6.注意

A主线程退出,其它线程不退出,主线程应调用pthread_exit

B避免僵尸线程

join

pthread_detach

pthread_create指定分离属性

被join线程可能在join函数返回前就释放完自己的所有内存资源,所以不应当返回被回收线程栈中的值;

C malloc和mmap申请的内存可以被其它线程释放

D如果线程终止时没有释放加锁的互斥量,则该互斥量不能再被使用

E应避免在多线程模型中调用fork,除非马上exec,子进程中只有调用fork的线程存在,其他线程在子进程中均pthread_exit

F信号的复杂语义很难和很多线程共存,应避免在多线程引入信号机制。

时间: 2024-10-05 18:39:53

3线程的终止方式,线程属性,NPTL的相关文章

Java多线程:“基础篇”09之interrupt()和线程终止方式

1. interrupt()说明 在介绍终止线程的方式之前,有必要先对interrupt()进行了解. 关于interrupt(),java的djk文档描述如下: http://docs.oracle.com/javase/7/docs/api/ Interrupts this thread. Unless the current thread is interrupting itself, which is always permitted, the checkAccess method of

学习Java多线程之线程定义、状态和属性_java

一 .线程和进程 1. 什么是线程和进程的区别: 线程是指程序在执行过程中,能够执行程序代码的一个执行单元.在java语言中,线程有四种状态:运行 .就绪.挂起和结束. 进程是指一段正在执行的程序.而线程有事也被成为轻量级的进程,他得程序执行的最小单元,一个进程可以拥有多个线程,各个线程之间共享程序的内功空间(代码段.数据段和堆空间)及一些进程级的资源(例如打开的文件),但是各个线程都拥有自己的棧空间. 2. 为何要使用多进程 在操作系统级别上来看主要有以下几个方面: - 使用多线程可以减少程序

java线程池当其中一个线程算出结果,终止全部线程

问题描述 java线程池当其中一个线程算出结果,终止全部线程 业务逻辑: 一个大型社区,每一秒有上千人在提交留言,提交的留言将经过,上万条的正则表达式的过滤,没有匹配任何规则的,才保存到系统,否则提示用户,您录入的内容不合法. 我是这样想的,把这上万条正则表达式,拆分成2000条一组,开一个5个线程的线程池,每个线程将负责其中2000个规则的匹配. 每条留言提交时,将由这5个线程,去判断是否有匹配的规则,如果其中一个线程匹配到了规则,将结束其他4个线程的任务,返回给用户结果. 请问这种要怎么实现

c++-如何随时终止C++线程的运行?

问题描述 如何随时终止C++线程的运行? 需要用在工业控制方面. 由于几乎每一句代码都会控制外部设备的运动,所以为了使外部设备能够及时停止运动,操作时可能随时会终止线程的执行. 例如一个工作线程: t1(LPVOID lparam) { while( true ) { move(1); move(2); move(3); move(4); } return 0; } 当我单击停止按钮时,不论t1执行到4步中的哪一步,线程必须停止执行并退出而非等待线程完全执行完毕.停止的位置可能是第一步,可能是第

《Java程序员面试秘笈》—— 1.7 等待线程的终止

1.7 等待线程的终止 在一些情形下,我们必须等待线程的终止.例如,我们的程序在执行其他的任务时,必须先初始化一些必须的资源.可以使用线程来完成这些初始化任务,等待线程终止,再执行程序的其他任务. 为了达到这个目的,我们使用Thread类的join()方法.当一个线程对象的join()方法被调用时,调用它的线程将被挂起,直到这个线程对象完成它的任务. 在本节中,我们将通过初始化资源的范例来学习join()方法. 准备工作本节的范例是在Eclipse IDE里完成的.无论你使用Eclipse还是其

深入Java线程管理(一):线程的实现方式

Java的线程实现方式一共有三种,继承Thread.实现Runable接口,实现Callable接口.不过实现Runnable接口与实现Callable接口的方式基本相同,只是Callable接口里定义的方法有返回值,可以声明抛出异常而已. 一. 继承Thread类创建线程类 1) 定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务. 2) 创建Thread子类的实例,即创建了线程对象. 3) 调用线程对象的start()方法来启动该线程.

java 实现线程同步的方式有哪些_java

什么是线程同步? 当使用多个线程来访问同一个数据时,非常容易出现线程安全问题(比如多个线程都在操作同一数据导致数据不一致),所以我们用同步机制来解决这些问题. 实现同步机制有两个方法: 1.同步代码块: synchronized(同一个数据){} 同一个数据:就是N条线程同时访问一个数据. 2. 同步方法: public synchronized 数据返回类型 方法名(){} 就是使用 synchronized 来修饰某个方法,则该方法称为同步方法.对于同步方法而言,无需显示指定同步监视器,同步

C#中的线程(二)线程同步

Keywords:C# 线程Source:http://www.albahari.com/threading/Author: Joe AlbahariTranslator: Swanky WuPublished: http://www.cnblogs.com/txw1958/Download:http://www.albahari.info/threading/threading.pdf    第二部分:线程同步基础   同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具: 简易

线程管理:守护线程的创建和运行

线程管理:守护线程的创建和运行 守护线程的创建和运行Java有一种特别的线程叫做守护线程.这种线程的优先级非常低,通常在程序里没有其他线程运行时才会执行它.当守护线程是程序里唯一在运行的线程时,JVM会结束守护线程并终止程序. 根据这些特点,守护线程通常用于在同一程序里给普通线程(也叫使用者线程)提供服务.它们通常无限循环的等待服务请求或执行线程任务.它们不能做重要的任务,因为我们不知道什么时候会被分配到CPU时间片,并且只要没有其他线程在运行,它们可能随时被终止.JAVA中最典型的这种类型代表