linux之线程
http://blog.csdn.net/lanyan822/article/details/7586845
POSIX线程数据类型:
pthread_t 线程标识符;
pthread_mutex_t 互斥量;
pthread_codet_t 条件变量;
pthread_key_t 线程私有权握访问键
pthread_attr_t 线程属性对象
pthread_mutexattr_t 互斥量属性对象
phtread_condattr_t 条件变量属性对象;
pthread_once_t 一次性初始化 控制变量
线程中的基本概念:
程序中使用线程标识符ID来表示线程。线程ID属于封装的pthread_t类型;
1.创建线程
Pthread系统中建立线程的主要方式是调用pthread_create. 如果进程的信号通知机制设为:SIGVE_THREAD, 当线程收到一个POSIX信号时也会创建一个线程。系统中可能还存在其他创建线程的方式
pthread_t pthread_id;
int status = pthread_create(&pthread_id, NULL, thread_func, NULL);
第三个参数:函数指针;
第四个参数:函数的参数指针;
关于thread_func(线程调用函数):
线程函数必须是如下形式,即返回类型为:void* , 参数类型为:void* ;
typedef void* (*func)(void* ); //不能写成typedef void* (*func)(void* i);
传、取参数的时候特别注意,传的时候要先转为void*, 取参数的的时候要转回原有的类型;(切记、切记)
2. 线程的启动(一般线程函数启动之后就被阻塞了,直到唤醒)
一旦线程来创建,最终它将开始执行机器指令。 初始指令序列将 带来 在pthread_create调用 中指定的 线程启动函数的执行。
线程启动函数 的运行参数 也是在创建线程时指定的,-----第四个参数;
在初始线程中, 线程的启动函数(即main函数) 是从程序外部被调用的。 (系统中有文件负责 初始化进程, 然后调用main函数)
初始化线程 与 普通线程 之间存在一些的不同。
a. main函数的调用参数( argc and argv )与普通线程的启动函数不同( void * 参数 )。
b.如果普通线程从启动函数中返回,则线程终止而其他线程依然可以运行;
但初始化进程从main函数中返回时,进程终止(进程内所有线程也被 终止)。
如果希望在初始化线程终止时,进程中的其他线程继续执行,则需要 在初始化线程中调用pthread_exit而不是从main函数返回;
c.在大多数系统中, 初始线程运行 在默认进程堆栈上; 该堆栈可以增长到足够的大小; 而在某些实现中,普通的堆栈空间是受限的, 如果线程堆栈溢出,则程序会因为段错误或者总线错误而失败;
3. 运行和阻塞
线程之所以会睡眠是因为 它需要的某个资源不可用(即被阻塞), 或者因为 系统将处理器分配给其他线程(即被抢占)
线程大多数时间处于其生命周期中的三个状态: 就绪, 运行 和阻塞;
线程在以下情况被阻塞:
1.试图加锁一个已经被锁住的互斥量;
2.等待某个条件变量;
3.调用Singwait等待尚未发生的信号;
4.执行无法立即完成的I/O操作
5.线程还有由于内存页错误之类的系统操作而被阻塞;
如果新线程此时没有运行, 则新线程将在主线程被阻塞后, 从就绪态 进入运行态。
当新线程运行完毕并返回时,主线程才会被解除阻塞,返回就绪态。
主线程 或者立即执行 或者 等到创建的线程 终止 后 重新运行直到结束;
调用pthread_join()函数 等待它创建的线程运行结束;
4.终止
线程通常从启动函数中返回来终止自己;
当调用 pthread_exit退出线程或者调用pthread_cancel 取消线程时, 线程在调用完每个清理过程中也将进入终止态; 这些清理过程 是由线程通过调用pthread_cleanup_push注册的;而且尚未通过调用 pthread_cleanup_pop删除;
线程还会有私有“线程特定数据”; 如果线程有非空的私有数据值,则与这些数据相关的 destructor函数将被调用;
如果线程已经被分离。 则它立刻进入下一个环节--------回收;
否则,线程处于终止态,它还可以被其他线程调用pthread_join 连接--------僵尸线程;因为即使它们已经死了;但还存在,僵尸线程可能会保存其运行时的大部分资源甚至是所有资源。因此不应该让线程长时间处于这种状态;
当创建不需连接的线程时,应该使用detachstate属性建立线程 使其自动分离;(还有第二种办法)
终止后线程至少保留了线程ID(pthread_t数据类型)和 void *返回值;
5.回收
分离一个正在运行的线程不会对线程带来任何影响,仅仅是通知系统当该线程结束时候,其所属资源可以被回收。
为了确保终止线程的资源对进程可用,应该在每个线程 结束时分离他们。一个没有被分离的线程终止时会保留其虚拟内存。包括他们的堆栈 和其他系统资源。
分离线程意味着 通知系统不再 需要此线程,允许系统将分配给它的资源回收;
如果使用detachstate属性(设为PTHREAD_CREATE_DETACH)建立线程; 或者 调用 pthread_detach分离线程, 则当线程结束时将立刻回收;
如果终止线程没有被分离,则它将一直处于终止态直到 1、被分离(通过pthread_detach分离) 或者 2、被连接(通过pthread_join)。
线程一旦被分离就不能再访问它;
回收将 释放 (所有线程 终止时未释放的系统 和进程资源,包括保存线程返回值的内存空间,堆栈,保存寄存器状态的内存空间等); 其中一些资源可能已在线程终止时被释放,
但必须记住:线程终止后上述资源就不该被访问了。 如果一个线程将其堆栈空间指针通过共享数据传给另一个线程,则该线程终止后,此数据就是陈旧数据了;
一旦 线程被回收,线程ID就无效了; 不能 再连接它、取消它或者执行其他任何操作。
终止线程ID(可能是系统数据结构地址)可能被分给新的线程;使用该ID调用pthread_cancel 可能会取消一个不同的线程,而不是返回一个ESRCH错误;
终止线程将释放所有系统资源,但必须自己先释放有该线程占有的程序资源,调用malloc 或者 mmap 分配的内存可以在任何时候,有任何线程释放。
互斥量、条件变量、和信号灯 可以由任何线程销毁。只要他们被解锁 并没有线程等待; 但是,只有互斥量的主人能够解锁它。 如果线程终止时还有加锁的互斥量。则该互斥量就不能被再次使用(因为不会被解锁)
pthread_exit()用于线程退出,可以指定返回值,以便其他线程通过pthread_join()函数获取该线程的返回值。
return是函数返回,只有线程函数return,线程才会退出。
exit是进程退出,如果在线程函数中调用exit,进程中的所有函数都会退出!
线程的终止
三种方式:
线程从执行函数返回,返回值是线程的退出码
线程被同一进程的其他线程取消
调用pthread_exit()函数退出。这里不是调用exit,因为线程调用exit函数,会导致线程所在的进程退出。
linux之线程的更多相关文章
- Linux/Unix 线程同步技术之互斥量(1)
众所周知,互斥量(mutex)是同步线程对共享资源访问的技术,用来防止下面这种情况:线程A试图访问某个共享资源时,线程B正在对其进行修改,从而造成资源状态不一致.与之相关的一个术语临界区(critic ...
- Linux获取线程tid线程名
Linux获取线程tid线程名 1 2 3 4 5 6 //thread name char cThreadName[32] = {0}; prctl(PR_GET_NAME, (unsigned l ...
- Linux编程---线程
首先说一下线程的概念.事实上就是运行在进程的上下文环境中的一个运行流.普通进程仅仅有一条运行流,可是线程提供了多种运行的路径并行的局面. 同一时候,线程还分为核心级线程和用户级线程.主要差别在属于核内 ...
- Linux 多线程 - 线程异步与同步机制
Linux 多线程 - 线程异步与同步机制 I. 同步机制 线程间的同步机制主要包括三个: 互斥锁:以排他的方式,防止共享资源被并发访问:互斥锁为二元变量, 状态为0-开锁.1-上锁;开锁必须由上锁的 ...
- Linux 默认线程栈大小 调优
Linux 线程栈介绍 栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的变量通常是局部变量.函数参数等:和堆相比,栈通常很小. Linux 查询线程栈 1.查看默认的 ...
- Linux内核线程创建
本文旨在简单介绍一下Linux内核线程: 先举个例子: 不插U盘,在Linux命令行中输入:ps -el:然后插上U盘,再次输入:ps -el 会发现多出了下面一行(当然还会有其他的,比如scsi相关 ...
- Linux 下线程的理解
2017-04-03 最近深入研究了下Linux线程的问题,发现自己之前一直有些许误解,特记之…… 关于Linux下的线程,各种介绍Linux的书籍都没有深入去解释的,或许真的如书上所述,Linux本 ...
- Linux中线程使用详解
线程与进程为什么有了进程的概念后,还要再引入线程呢?使用多线程到底有哪些好处?什么的系统应该选用多线程?我们首先必须回答这些问题. 使用多线程的理由之一是和进程相比,它是一种非常"节俭&qu ...
- Linux中线程的挂起与恢复(进程暂停)
http://www.linuxidc.com/Linux/2013-09/90156.htm 今天在网上查了一下Linux中对进程的挂起与恢复的实现,相关资料少的可怜,大部分都是粘贴复制.也没有完整 ...
- linux系统——线程
linux系统线程 1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的Unix也支持线程的概念,但是在一个 ...
随机推荐
- CSS3 Test
CSS3Test 如何判定一个浏览器对css3的支持情况呢 有这么一个站点http://css3test.com 可以测试浏览器对CSS3的支持情况 对应的Github在这里 原理 实际上浏览器对CS ...
- @RISK
Price: AUD $3,295.00 Price: AUD $2,495.00 适用于项目管理的 @RISK 免费试用版下载 » 立即购买 » 价格对比 » 许可选项 (英文) » 教学计 ...
- ANDROID SHAPE画圆形背景_ANDROID实现角标布局
ANDROID SHAPE画圆形背景_ANDROID实现角标布局 <?xml version="1.0" encoding="UTF-8"?> &l ...
- rsyslog 传输mysql 日志
在另外一种环境中,让我们假定你已经在机器上安装了一个名为"foobar"的应用程序,它会在/var/log下生成foobar.log日志文件.现在,你想要将它的日志定向到rsysl ...
- MFC上下浮动与渐入渐出消息提示框实现
类似QQ与360软件,消息提示有两种.上下浮动.渐入渐出. 1.上下浮动提示框实现 机制,定时器响应上下浮动消息. 主要API:MoveWindow. 源码如下UpDownTipDlg.h.UpDow ...
- ubuntu下编译内核驱动。
目的: 1. 驱动热身.网上有很多类似的文章可供参考. 2. 在操作系统中, 编写这个设备的驱动. 3. 为写qemu的watchdog驱动练手. 有朋友问make的 watchdog驱动 需要什么准 ...
- #include <string>
1 append(string T&);字符串拼接 2 c_str string.c_str是Borland封装的String类中的一个函数,它返回当前字符串的首字符地址. 3 empty() ...
- Java面试题之四
十六.运行时异常与一般异常有何异同 Java提供了两类主要的异常:runtime exception和checked exception. 1.checked exception:这种异常也就是我们 ...
- oracle 与sql server 部分内置函数替换
1,trunc--convert oracle: select trunc(sysdate) from dual 输出:2016/5/24 sql server:select CONVERT(va ...
- C++_基础_继承、多态
内容: (1)子类中的拷贝构造和拷贝赋值 (2)多继承和虚继承 (3)多态的初识 (4)虚析构的特性和使用 (5)多态的底层实现 (6)纯虚函数.抽象类的概念 1.子类中的拷贝构造和拷贝赋值 子类中的 ...