线程基本概念:

1 线程

  (1)概念:linux下没有真正的线程,所谓的线程都是通过进程的pcb模拟的,因此linux下的线程也称为“轻量级进程”,之前我们所说的进程现在看来,可以理解为:只有一个线程的线程组。也可以将线程理解为:在一个程序里的一个执行路线,更准确的来说,线程是一个进程内部的控制序列

  (2)进程:至少有一个线程的线程组

  (3)linux下的pcb是task_struct,task_struct中的tgid是线程组id,也等于第一个进程的pid,如果再创建新的线程,这些线程的tgid会相同

2 线程和进程

  (1)进程是资源竞争的基本单位

  (2)线程是程序执行的最小单位

  (3)线程共享进程的数据,比如进程的正文段,数据段,文件描述符(代表一个线程打开文件,另一个线程也可以拿着文件描述在安全的前提下进行操作),信号的处理方式,当前工作目录,用户id,组id。但线程也有自己独有的资源:栈,上下文数据,errno全局变量,信号屏蔽字,调度优先级等等。(注:这些独有的数据都存放在虚拟地址空间的共享区)

  (4)进程和线程的关系如下图:

3 线程的优点:

  (1)创建一个线程的代价要比创建一个线程的代价小的多

  (2)与进程之间的切换先比而言,线程之间的切换需要操作系统做的工作很少

  (3)线程占有的资源要比进程小很多

  (4)能充分利用多处理器的可并行数量

  (5)在等待慢速I/O操作结束的同时,程序可执行其他的计算任务

  (6)线程多用于cpu密集型与I/O密集型程序

4 线程的缺点:

  (1)性能损失:在有的情况下会增加额外的调度与同步开销(比如有的操作无法与其他线程共享处理器,当这种操作的数量大于处理器的数量时,会产生这种情况)

  (2)健壮性降低:线程切换之间缺乏安全保护,需要额外的操作保证线程对共享资源的安全访问

  (3)缺乏访问控制:进程是访问控制的基本粒度,在一个线程中调用某些OS函数会对整个进程造成影响

  (4)编程难度较高

线程控制

注意:我们所使用的是大佬们封装的一套接口,因此所使用的都是库函数,所以也说这套接口创建的线程是用户态线程,并且这个用户态线程在操作系统中对应了一个轻量级进程

1 线程创建

  int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);

  参数:第一个参数返回线程id,第二个参数表示要设置线程的属性,第三个参数表示线程启动后要执行的函数,第四个参数表示创个线程启动函数的参数

  返回值:成功返回0,失败返回错误码

2 线程终止

  void pthread_exit(void *value_ptr);

  参数:输出型参数,带出线程退出时的返回值,不能讲局部变量的地址传给它;

  无返回值

  int pthread_cancel(pthread_t thread);

  功能:同一进程中的其他线程,可以取消另一个线程

  参数:线程id

  返回值:成功返回0,失败返回错误码

3 线程等待与分离

  (1)需要线程等待的原因:已经退出的线程,其空间没有释放,仍然在进程地址空间中,创建新的线程不会覆盖退出线程的空间,因此为了避免内存泄漏,需要线程等待,获取线程的退出状态,并且允许系统回收资源

  (2)int pthread_join(pthread_t thread, void** value_ptr)

    参数:第一个参数:表示需要等待线程的线程id,第二个参数是输出型参数,指向一个指针,表示线程的退出状态返回值,传NULL表示不关心返回状态

    返回值:成功返回0,失败返回错误码

  注意:只有线程处于joinable状态,这个线程才能被等待,此状态是线程的默认属性;除此之外,还有detach状态,此状态表示线程退出后直接释放资源,线程无法被等待。线程的这两个属性是互斥的,二者只能选其一

  (3)分离线程:int pthread_detach(pthread_t thread)

    int pthread_detach(pthread_self())

线程的同步与互斥

  大部分情况下,线程使用的数据都是局部变量,变量的地址空间在线程地址空间中,这种情况下,变量归单个线程,其他线程无法获得这种变量;但有时候,很多变量都需要在线程间共享,这样的变量称为共享变量,可以通过数据的共享,完成线程之间的交互;多个线程并发的操作共享变量,会引发一些问题;因此需要通过同步与互斥实现一定的保护机制

1 互斥量

  互斥:同一时间理解资源的唯一访问性

  互斥锁是原子操作 

  (1)定义胡互斥锁变量:pthread_mutex_t mutex

  (2)初始化变量:pthread_mutex_init(&mutex)

  (3)临界资源加锁/解锁

    pthead_mutex_lock(&mutex)

    pthread_mutex_unlock(&mutex)

    pthread_mutex_trylock(&mutex):非阻塞

    pthread_mutex_timelock(&mutex)

  (4)销毁互斥锁:

    pthread_mutex_destory(&mutex)

2 条件变量

  当一个线程互斥的访问某个变量时,他可能发现在其他线程改变状态之前什么也做不了:例如当一个线程访问队列时,发现队列为空,它只能等待其他线程将一个节点添加到队列中,这种情况下需要条件变量

  (1)初始化

    pthread_cond_init(&cond)

  (2)销毁

    pthread_cond_destory(&cond)

  (3)等待条件满足

    pthread_cond_wait(&cond,&mutex)

    注意:为了保护条件的修改,所以我们使用了互斥锁进行保护,但是如果加锁之后条件不满足而陷入休眠,则造成死锁,因此在休眠之前先解锁,但是解锁和休眠应该是原子操作,,否则也可能会诱发死锁的情况出现

  (4)唤醒等待

    pthread_cond_signal(&cond)   只通知一个

    pthread_cond_broadcast(&cond)  唤醒所有等待的线程

3 死锁产生的必要条件

  (1)互斥条件

  (2)不可剥夺条件

  (3)请求与保持条件

  (4)环路等待条件

4 预防死锁

  破坏其中的一个条件

  银行家算法

  死锁检测算法

线程&线程控制的更多相关文章

  1. Java多线程之线程的控制

    Java多线程之线程的控制 线程中的7 种非常重要的状态:  初始New.可运行Runnable.运行Running.阻塞Blocked.锁池lock_pool.等待队列wait_pool.结束Dea ...

  2. 线程锁的本质:线程控制、线程状态控制 while if:根据线程的关系(模式)协调线程的执行

    线程锁的本质:线程控制.线程状态控制 while if https://www.cnblogs.com/feng9exe/p/8319000.html https://www.cnblogs.com/ ...

  3. java多线程中篇(三) —— 线程的控制(创建,运行,阻塞,中断,结束)

    简介 线程的控制就是程序对线程的主要管理,最重要的就是状态的切换维护. 每种转态都有不同的引发事件(对应线程的方法),每种状态又有各自不同的处理步骤和过程,整个线程控制主要就是涉及这些内容. 正文 线 ...

  4. JAVA之旅(十五)——多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止

    JAVA之旅(十五)--多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止 我们接着多线程讲 一.生产者和消费者 什么是生产者和消费者?我们 ...

  5. 常量,字段,构造方法 调试 ms 源代码 一个C#二维码图片识别的Demo 近期ASP.NET问题汇总及对应的解决办法 c# chart控件柱状图,改变柱子宽度 使用C#创建Windows服务 C#服务端判断客户端socket是否已断开的方法 线程 线程池 Task .NET 单元测试的利剑——模拟框架Moq

    常量,字段,构造方法   常量 1.什么是常量 ​ 常量是值从不变化的符号,在编译之前值就必须确定.编译后,常量值会保存到程序集元数据中.所以,常量必须是编译器识别的基元类型的常量,如:Boolean ...

  6. 线程&线程池

    线程 进程和线程: 进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位. 注意:两个都是过程 线程一个特点: 一个进程中,多个线程共享资源 线程和进程区 ...

  7. Java线程 : 线程同步与锁

    一.同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. public ...

  8. C#线程 线程进阶

    第四部分:高级线程 非阻塞同步 前面我们说过,即使在分配或增加字段的简单情况下,也需要同步.尽管锁定始终可以满足此需求,但是竞争性锁定意味着线程必须阻塞,从而遭受上下文切换的开销和调度的延迟,这在高度 ...

  9. Linux线程的实现 & LinuxThread vs. NPTL & 用户级内核级线程 & 线程与信号处理

    另,线程的资源占用可见:http://www.cnblogs.com/charlesblc/p/6242111.html 进程 & 线程的很多知识可以看这里:http://www.cnblog ...

  10. Linux线程 之 线程 线程组 进程 轻量级进程(LWP)

    Thread Local Storage,线程本地存储,大神Ulrich Drepper有篇PDF文档是讲TLS的,我曾经努力过三次尝试搞清楚TLS的原理,均没有彻底搞清楚.这一次是第三次,我沉浸gl ...

随机推荐

  1. 数学小知识点整理(TBC)

    文章目录 前言 素数与同余 线性筛部分 素数 线性递推逆元 指数循环节降幂 当求逆元时模数与求逆元的数有可能不互质时的处理方法 一个神奇的结论 拓展欧拉定理 杂乱的一些性质/技巧 二进制枚举子集 异或 ...

  2. 2019.02.06 bzoj2987: Earthquake(类欧几里得)

    传送门 题意简述:求满足ax+by+c≤0ax+by+c\le0ax+by+c≤0的二元组(x,y)(x,y)(x,y)对数. 思路: 类欧几里得算法模板题. 把式子变化一下变成:求满足0≤y≤−ax ...

  3. 半透明全屏蒙层+全屏屏蔽+内容居中+css

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. 修改oralce数据库用户名和密码

    首先以sys用户登录数据库 一.修改用户名 查到到所需修改用户名称的用户需要:select user#,name from user$;(例如查到有一个normal的用户对应的user#=61) 修改 ...

  5. C++中的public、protected 及 private 用法

    首先需要明白几点: 1,类的一个特性就是封装,public 和 private 作用就是实现这一目的的. 用户代码(类外)可以访问public成员而不能访问private成员:private成员只能由 ...

  6. (区间dp + 记忆化搜索)Treats for the Cows (POJ 3186)

    http://poj.org/problem?id=3186   Description FJ has purchased N (1 <= N <= 2000) yummy treats ...

  7. URAL1099. Work Scheduling(一般图匹配带花树开花算法)

    1099. Work Scheduling Time limit: 0.5 second Memory limit: 64 MB There is certain amount of night gu ...

  8. 6、GNU makefile工程管理学习的一个例子

    在之前我们已经学习了一个文件的编译过程,但是做过项目的都知道,一个工程中的源文件不计其数,其按类型.功能.模块会分别放在若干个目录中,而这些文件如何编译就需要有一个编译规则,虽然现在很多大型的项目都是 ...

  9. 《mysql必知必会》学习_第13章_20180803_欢

    第13章:分组过滤. P83 select count(*) as num_prods from products where vend_id=1003; #返回vend_id=1003的产品数目总值 ...

  10. WINDOWS CLUSTER -- 时间不同步导致的群集问题

    故障描述,重启服务器后,发现该重启节点未成功加入到Windows群集中,导致该节点上的Alwayson服务也受影响处于“正在解析”状态,尝试重启cluster服务,发现无效,查看windows日志,发 ...