[17]APUE:线程
通常情况下,线程模型的并发性能优于进程模型,但不总是这样
线程的优势:
- 线程的创建、销毁及上下文切换代价比进程低
- 某些情况下,使用线程可以简化逻辑,避免异步编程的复杂性
- 同一进程内所有线程共享全局内存段,没有进程间通信的开销
线程的劣势:
- 线程之间协作的顺序(时序)是完全随机的,*nix 内核的实现中也不包括对线程时序的完全控制,线程的不可控特性可能会带来某些测试过程中难以复现的 BUG,业务风险较高
- 线程之间的数据共享,同时也带来了数据竞争的问题,需要十分谨慎地的处理临界区数据
*nix 平台下的线程实现
- 在内核层面的实现中,线程本质上还是进程模型,用户空间看到的每一线程,都对应于内核中一个进程(lwp:light weight process),用户空间的进程 ID,对应于内核层面的进程组 ID
- 线程的并发性能提升并非线性增长,各种锁机制的存在,都会造成线程并发性能的降低
- 多线程编程需要对特定硬件平台的特性有更深入的了解,否则容易陷入“伪共享”等硬件相关的性能瓶颈中
线程的创建与终止
#include <pthread.h>
//pthread_* 类的函数成功返回 0;出错时,直接返回错误码,同时也会设置 errno
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
void pthread_exit(void *retval);
pthread_t pthread_self(void);
- pthread_self 函数用于线程取得自身的线程 ID
- 此处的 ID 是用户空间的概念,只在线程所属的进程环境下有意义,通常情况下就是一个指向特定结构体的内存地址(Linux/FreeBSD)
- 操作系统范围内可以重复,同一进程中的线程退出后,其 ID 也可以立即被复用
- 线程执行函数中调用 return 也可以终止自身
释放线程所占用的资源
#include <pthread.h>
int pthread_detach(pthread_t thread);
int pthread_join(pthread_t thread, void **retval);
- 调用 pthread_detach(pthread_self()) 可使线程自身处于 detach 处态,线程退出后,其占用的资源将自动释放
- 同一进程环境中的其它线程可以使用 pthread_join 函数获得指定线程的退出状态,同时释放其所占用的资源
线程属性设置
#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr); int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);
- 线程属性设置使用 pthread_attr_t 数据类型,必须首先调用 pthread_attr_init 初始化之后才能使用,使用完成之后需要调用 pthread_attr_destroy 释放资源
- pthread_attr_setdetachstate 函数中 detachstate 参数的可选值有:PTHREAD_CREATE_JOINABLE、PTHREAD_CREATE_DETACHED,默认是前者,效果与线程自身调用 pthread_detach(pthread_self()) 相同
线程 ID 比较
int pthread_equal(pthread_t t1, pthread_t t2);
- 不同操作系统中的线程实现方式存在差异,不能直接用 '==' 判断
线程清理函数
#include <pthread.h>
void pthread_cleanup_push(void (*cleanup_routine)(void *), void *arg);
void pthread_cleanup_pop(int execute);
- 不同的操作系统中,pthread_cleanup_push 与 pthread_cleanup_pop 可以实现为宏或函数,使用时必须一一配对使用,执行顺序与设置顺序相反,与进程清理中的 atexit 函数类似
- pthread_cleanup_pop 的参数为 0 时,将不执行对应的清理行为
- 在实现为宏的平台上(如:FreeBSD、MAX OS),函数退出必须调用 pthread_exit,而不能使用 return 返回,否则清理动作将得不到执行
[17]APUE:线程的更多相关文章
- APUE 线程 - 程序清单
APUE 线程 - 程序清单 程序清单11-1 打印线程ID #include "util.h" #include<pthread.h> pthread_t ntid; ...
- <<APUE>> 线程
一个进程在同一时刻只能做一件事情,线程可以把程序设计成在同一时刻能够做多件事情,每个线程处理各自独立的任务.线程包括了表示进程内执行环境必需的信息,包括进程中标识线程的线程ID.一组寄存器值.栈.调度 ...
- Java基础学习总结(17)——线程
一.线程的基本概念 线程理解:线程是一个程序里面不同的执行路径 每一个分支都叫做一个线程,main()叫做主分支,也叫主线程. 程只是一个静态的概念,机器上的一个.class文件,机器上的一个.exe ...
- <<APUE>> 线程的分离状态
在任何一个时间点上,线程是可结合的(joinable),或者是分离的(detached).一个可结合的线程能够被其他线程收回其资源和杀死:在被其他线程回收之前,它的存储器资源(如栈)是不释放的.相反, ...
- APUE线程控制
一.线程的限制 sysconf可以查看的值 PTHREAD_DESTRUCTOR_ITERATIONS 线程退出时操作系统实现试图销毁线程特定数据的最大次数 _SC_THREAD_DESTRUCTOR ...
- apue 外传
先上目录 chapter 3 [apue] dup2的正确打开方式 chapter 10 [apue] 等待子进程的那些事儿 chapter 14 [apue] 使用文件记录锁无法实现父子进程交互执行 ...
- java多线程系类:JUC线程池:05之线程池原理(四)(转)
概要 本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略 ...
- 线程与并发系列一:Lock、Monitor、UserSpinLock
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using S ...
- linux 线程函数大全
Technorati 标签: Linux thread 索引: 1.创建线程pthread_create 2.等待线程结束pthread_join 3.分离线程pthread_detach 4.创建线 ...
随机推荐
- J2EE学习篇之--JQuery技术详解
前面我们讲解了的J2EE的技术都是服务端的技术,下面我们来看一下前端的一些开发技术,这一篇我们来看一下jQuery技术 简介: jQuery由美国人John Resig创建,至今已吸引了来自世界各地的 ...
- 二分+贪心——cf1251D
二分的时候要特别注意一下下界L #include<bits/stdc++.h> using namespace std; #define ll long long #define N 20 ...
- BZOJ 3252: 攻略(思路题)
传送门 解题思路 比较好想的一道思路题,结果有个地方没开\(long\) \(long\) \(wa\)了三次..其实就是模仿一下树链剖分,重新定义重儿子,一个点的重儿子为所有儿子中到叶节点权值最大的 ...
- noip1998 提高组t3 挖地雷
题目背景 NOIp1996提高组第三题 题目描述 在一个地图上有N个地窖(N<=20),每个地窖中埋有一定数量的地雷.同时,给出地窖之间的连接路径.当地窖及其连接的数据给出之后,某人可以从任一处 ...
- mysql笔试题大餐---1、组合查询方式及having
mysql笔试题大餐---1.组合查询方式及having 一.总结 一句话总结: 实践:我之前的mysql真的学的太浅了,这种情况下,依据实践(做题)才是唯一能把它学好的方式 学的暂时够了,以实践而学 ...
- error C3861: “L”: 找不到标识符
提示错误的语句:::CLSIDFromProgID(L("Shell.Application"), &clsid); 解决办法: 出现上面的错误是因为语法错误了,去掉字符串 ...
- ORM-Dapper:Dapper百科
ylbtech-ORM-Dapper:Dapper百科 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 作者:ylbtech出处:htt ...
- java有序列表
关于有序和无序的定义: 有序:有序列表中的元素具有某种内在的关联,这种关联定义了列表之间的顺序 无序:无序列表中的元素按使用者所选择得任意方式排序 索引:索引列表为他的元素维护一段连续的数字索引值 有 ...
- 进程共享变量#pragma data_seg用法
#pragma data_seg介绍 用#pragma data_seg建立一个新的数据段并定义共享数据,其具体格式为: #pragma data_seg ("shareddata" ...
- Flyway - Version control for your database
Flyway 是什么? Flyway是个数据库版本管理工具.在开发过程中,数据库难免发生变更,例如数据变更,表结构变更.新建表或者视图等等. 在项目进行时无法保证一旦开发环境中的数据库内容变化候会去测 ...