线程:轻量级进程,在资源、数据方面不需要进行复制

不间断地跟踪指令执行的路径被称为执行路线

进程的结构:task_struck;地址空间

线程:轻量级的进程

在同一个进程中创建的线程,在共享进程的地址空间

在linux里用task_struct来描述一个线程,进程和线程都参与统一的调度

线程是共享相同地址空间的多个任务

------------------------------------------------------------------------------------

一个进程中的多个线程共享以下资源:

1.代码段/指令

** 2.静态数据(全局变量、静态变量)

3.进程中打开的文件描述符

4.信号处理函数

5.当前工作目录

6.用户id:uid

7.组id:gid

每个线程私有的资源如下:

1.线程id:tid

2.程序计数器(PC)和寄存器

** 3.栈/堆栈(stack):局部变量

4.错误码(errno)

5.信号掩码

6.执行状态和属性

-----------------------------------------------------------------------------------------------

创建线程:

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

thread:创建的线程的id号

attr:指定线程的属性,NULL-----表示使用缺省属性,默认

start_routine:线程执行的函数

void *(*start_routine) (void *)--------------参数和返回值都被定义为类型是void*的指针,以允许他们指向任何类型的值

arg:传递给线程执行的函数的参数

删除线程/线程退出:

void pthread_exit(void *retval);

retval:线程退出时,返回值的地址

控制线程:等待一个线程结束/以阻塞的方式等待线程的结束

int pthread_join(pthread_t thread, void **retval);

thread:要等待的进程

retval:指向线程返回值的地址,不需要的话---NULL

======================================================================================================

|    在进行多线程编程时,一般主线程初始化/创建其他线程后,不做任何操作,调用pthread_join等待线程结束 |

| 因为若主线程有操作的话,可能因为操作失误而关闭进程,这样就会影响其他的线程操作                   |

======================================================================================================

线程间互斥和同步:

----------------------------------------------------------------------------------------------------------------------------------------------------

线程间同步(条件变量):

条件变量是线程的一种同步机制。

条件变量给多个线程提供一个汇合的场所

条件变量是公共资源,条件变量与互斥锁一起使用,允许线程以没有竞争的方式等待特定的条件发生。

条件变量是由互斥锁进行保护的。线程在改变条件变量的状态之前,必须先锁住互斥锁。

初始化条件变量:

int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);

attr---->条件变量的属性

NULL---->默认属性

或者

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

等待条件变量:

int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);

功能:1.先解锁

2.暂停该线程

唤醒条件变量:

int pthread_cond_signal(pthread_cond_t *cond);

功能:使一个由cond阻塞的线程运行

-----------------------------------------------------------------------------------------------------------------------------------------------------------

线程间互斥:引入互斥锁(mutual exclusion)目的是用来保证共享数据操作的完整性和正确性

互斥锁:主要用来保护临界资源。每个临界资源都由一个互斥锁来保护,任何时候最多只有一个线程能访问临界资源。进程必须要先获得互斥锁才能访问临界资源,访问完临界资源后释放互斥锁。如果无法获得互斥锁,线程就会阻塞/等待,直到获得锁为止。

初始化互斥锁:int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);

mutex----------互斥锁

attr----------互斥锁的属性,NULL---表示缺省/默认属性

或者

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

加锁:等待互斥锁解开然后再锁住互斥锁

int pthread_mutex_lock(pthread_mutex_t *mutex);

解锁:int pthread_mutex_unlock(pthread_mutex_t *mutex);

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

信号量:bijkstra算法

信号量也是一种同步的机制

由信号量来决定线程是继续运行还是阻塞等待

信号量代表一类资源,他的值表示系统中该资源的数量

信号量是受保护的变量,只能通过函数来访问

初始化信号量:

int sem_init(sem_t *sem, int pshared, unsigned int value);

sem:初始化的信号量

pshared:信号量的共享范围,0-----线程之间   !0------进程之间

value:信号量的初始值

申请资源( P 操作):

if(信号量 > 0)

{

信号量-1;

申请资源的任务继续运行;

}else

{

申请资源的任务阻塞等待;

}

int sem_wait(sem_t *sem);

int sem_trywait(sem_t *sem);

int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

释放资源( V 操作):

if(没有任务等待资源)

{

信号量+1;

}else

{

唤醒第一个等待的任务,让这个任务继续运行;

}

int sem_post(sem_t *sem);   //唤醒信号量

---------------------------------------------------------------------------------------------------------------------------------------------

Posix 定义的信号量:

**   无名信号量

有名信号量

linux线程的更多相关文章

  1. [转载]Linux 线程实现机制分析

    本文转自http://www.ibm.com/developerworks/cn/linux/kernel/l-thread/ 支持原创.尊重原创,分享知识! 自从多线程编程的概念出现在 Linux ...

  2. linux线程的实现

    首先从OS设计原理上阐明三种线程:内核线程.轻量级进程.用户线程 内核线程 内核线程就是内核的分身,一个分身可以处理一件特定事情.这在处理异步事件如异步IO时特别有用.内核线程的使用是廉价的,唯一使用 ...

  3. linux线程的实现【转】

    转自:http://www.cnblogs.com/zhaoyl/p/3620204.html 首先从OS设计原理上阐明三种线程:内核线程.轻量级进程.用户线程 内核线程 内核线程就是内核的分身,一个 ...

  4. Linux线程-创建

    Linux的线程实现是在内核以外来实现的,内核本身并不提供线程创建.但是内核为提供线程[也就是轻量级进程]提供了两个系统调用__clone()和fork (),这两个系统调用都为准备一些参数,最终都用 ...

  5. Linux线程学习(一)

    一.Linux进程与线程概述 进程与线程 为什么对于大多数合作性任务,多线程比多个独立的进程更优越呢?这是因为,线程共享相同的内存空间.不同的线程可以存取内存中的同一个变量.所以,程序中的所有线程都可 ...

  6. Linux线程学习(二)

    线程基础 进程 系统中程序执行和资源分配的基本单位 每个进程有自己的数据段.代码段和堆栈段 在进行切换时需要有比较复杂的上下文切换   线程 减少处理机的空转时间,支持多处理器以及减少上下文切换开销, ...

  7. Linux 线程(进程)数限制分析

    1.问题来源公司线上环境出现MQ不能接受消息的异常,运维和开发人员临时切换另一台服务器的MQ后恢复.同时运维人员反馈在出现问题的服务器上很多基本的命令都不能运行,出现如下错误:2.   初步原因分析和 ...

  8. Linux 线程与进程,以及通信

    http://blog.chinaunix.net/uid-25324849-id-3110075.html 部分转自:http://blog.chinaunix.net/uid-20620288-i ...

  9. linux 线程的内核栈是独立的还是共享父进程的?

    需要考证 考证结果: 其内核栈是独立的 206 static struct task_struct *dup_task_struct(struct task_struct *orig) 207 { 2 ...

  10. Linux 线程模型的比较:LinuxThreads 和 NPTL

    Linux 线程模型的比较:LinuxThreads 和 NPTL GNU_LIBPTHREAD_VERSION 宏 大部分现代 Linux 发行版都预装了 LinuxThreads 和 NPTL,因 ...

随机推荐

  1. 常见ES5方法

    • ES5 JSON扩展JSON.parseJSON.stringify • ES5 Object扩展Object.createObject.keys • Date对象Date.now • ES5 F ...

  2. hibernate学习二(HelloWorld)

    一.建立hibernate配置文件 在工程Hibernate_01_HelloWorld下的src上建立hibernate.cfg.xml,打开hibernate-release-4.3.11.Fin ...

  3. Android之分页加载数据

    基本的原理和我的上一篇随笔“Android之下拉刷新ListView”差不多,代码里面有注释,这里就不废话了,直接上代码. 自定义的分页显示ListView——PagedListView.java代码 ...

  4. python动态创建类的声明

    动态创建类的声明 使用内置函数type,原型:class type(name, bases, dict)name是类的名字,相当于__class__bases是类的基类,元组,可以有多个基类,但是基类 ...

  5. 07-本地 YUM 源制作

    1.YUM相关概念 1.1.什么是YUM YUM(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器.基 ...

  6. .net MVC中异常日志

    在日常工作中,我们有些项目可能进入了维护期,但是项目可能存在一些潜伏较深的bug导致我们在测试阶段并未发现,那么错误日志记录为我们的项目维护起着重要的作用.记录系统日志的方法如下 1.在系统根目录建立 ...

  7. 小小C程序(九九乘法表)

    用一个简单的嵌套循环实现: #include <stdio.h> int main() { int i,j; ,j=i;i<=&&j<=;) { if (i== ...

  8. LPC43xx系列使用IAP的注意事项

    LPC43xx系列使用IAP的注意事项 Tags: LPC43xx IAP 单片机 LPC43xx IAP函数的调用 一般MCU的IAP是,厂商固化一段代码在芯片的某个区域,然后告诉你这个代码的入口地 ...

  9. JSON格式序列化与反序列化(List、XML)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

  10. iOS中为什么block用copy属性

    1. Block的声明和线程安全Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非ARC ...