Linux编程---线程


首先说一下线程的概念.其实就是运行在进程的上下文环境中的一个执行流.普通进程只有一条执行流,但是线程提供了多种执行的路径并行的局面.

同时,线程还分为核心级线程和用户级线程.主要区别在属于核内还是核外.

核心级线程,地位基本和进程相当,由内核调度.也就是说这种系统时间片是按线程来分配的.这种线程的好处就是可以适当的运用SMP,即针对多核CPU进行调度.

用户级线程,在用户态来调度.所以相对来说,切换的调度时间相对核心级线程来说要快不少.但是不能针对SMP进行调度.

对于现在的系统来说,纯粹的用户级线程只存在于实验室中吧.

对于Linux中实现的线程来说,支持LWP(轻量级进程).把用户级线程映射到内核级上.简单来说,Linux只有内核级进程,不存在真正的线程.但是我们也可以把LWP叫做线程.

线程和进程对操作系统来说相当于是平行的关系,但大部分资源是隶属于进程的.如果进程挂了,全部线程也会终止.(直接赋值其进程的页表,然后修改特殊的部分即可创建一下线程~复习一下虚拟存储~)

顺带一提erlang虚拟机下的轻量级线程似乎就是用户级线程.我记得在哪看过,说erlang切换线程比c执行的线程切换还快.这里erlang的线程概念和用户级线程概念又不一样.是erlang虚拟机自己实现的线程,叫做用户线程.(没有’级’字,操作系统概念还真是绕啊..).这是由于Linux只有LWP造成的.

这里我有个疑问,就是Linux的线程是否是环保线程.这个概念也是今天刚看<现代操作系统>中提到的.意思就是对于进程来说,线程并不立即释放资源,而是等到进程结束再释放.这样就省去了线程重新生成的开销.对于服务器来说应该是很有用的一个策略呢.有知道的吗?

在Linux中使用线程 

Linux中多线程的实现

Linux多线程──生产者消费者

Linux多线程──读者写者问题

Linux基础编程 多线程中的互斥锁 pthread_mutex_lock

Linux基础编程 多线程同步 pthread_cond_signal

--------------------补充说明分割线-----------------------

又看了些书.发现实际上linux的线程创建过程主要调用的是clone函数.

这个函数的第二个参数有好几种状态选择.这些选择决定了clone出来的进程是一般所说的线程还是一个进程.

并且有以下几种标志可以选择:

CLONE_VM 置1:创建线程--共享地址空间  置0:创建进程,不共享地址空间,但会复制

CLONE_FS 共享umask 不共享

CLONE_FILES 共享文件描述符 复制文件描述符

CLONE_SIGHAND 共享信号句柄表 赋值信号句柄表

CLONE_PID 新线程获得旧的PID 新线程获得自己的PID

CLONE_PARENT 新线程与调度这有相同的父亲 新线程的父亲是调用者

Linux对进程标识符PID和任务标识符TID进行了区分!!并且两个都在task_struct结构中.

当用clone函数创建一个新进程而不需要和旧进程共享任何信息时,PID被设置成一个新值(新进程?fork?).否则任务得到一个新的任务标识符,但是PID不变.

TID也就是我后面会说的线程标识符.

估计pthread库中,应该就是把这些标志都选上,然后创建的.

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

使用线程的程序一般具有一下特征:

1.能够与其他任务并行执行.

2.有可能会被阻塞较长时间,但这时候其他进程可并发执行.

3.需要回应异步事件.毕竟异步本身就是不确定阻塞时间的.

4.线程使用CPU的时间足够长.不然切换的代价也不少.

这里要写的是Pthread线程.也就是POSIX定义的线程接口.这个接口包含100多个函数,所有函数名都已pthread_开头.功能上大致分为三类:

线程管理: 这类函数负责线程的创建,终止,汇合,取消,以及县城属性的设置和查询等.

线程同步: Pthread提供了互斥变量,条件变量,栅栏(屏障)变量等手段支持线程间的同步.

操作线程专有数据: 多线程程序中,全局数据分为所有线程都可以访问的共享数据和单个线程内所有函数都可以访问的线程专有数据.

这里要注意一点:所有函数都部通过errno来报错.执行成功均返回0.除开pthread_getspecific完全不报错之外,其余的返回错误号.

但是对于单独的一个线程,报错的时候修改你的errno,其他线程是无法干扰的.实际上Linux的errno是一个局部变量(这里也是网上查的,不过都是很老的帖子里面的,有错误请指正)

线程标识:

pthread_t pthread_self(void);  用于获得线程ID,即TID

pthread_equal(pthread_t t1,pthread_t t2);  用于比较两个线程标号,pthread_t可能并不是整形.

更多详情见请继续阅读下一页的精彩内容:

  • 1
  • 2
  • 3
  • 4
  • 下一页

相关内容