linux的进程

Published: 28 Oct 2015 Category: linux

1、进程地址空间内容

Linux进程地址空间的一步步探究

2、RTOS

RTOS,即:实时系统(Real-time operating system),实时系统能够在指定或者确定的时间内完成系统功能和外部或内部、同步或异步时间做出响应的系统。它的正确性不仅依赖系统计算的逻辑结果, 还依赖于产生这个结果的时间。因此实时系统应该在事先先定义的时间范围内识别和处理离散事件的能力;系统能够处理和储存控制系统所需要的大量数据。

任务是RTOS中最重要的操作对象,每个任务在RTOS的调用下由CPU分时执行。任务的调度目前主要有时间分片式、轮流查询式和优先抢占式三种,不同的 RTOS可能支持其中一种或几种,其中优先抢占式对实时性的支持最好

3、CAS

CAS原子操作——Compare & Set,或是 Compare & Swap,现在几乎所有的CPU指令都支持CAS的原子操作,X86下对应的是 CMPXCHG 汇编指令。

无锁操作在性能上远远优于加锁操作,消耗时间仅为加锁操作的1/3左右,无锁编程方式确实能够比传统加锁方式效率高,经上面测试可以发现,可以快到3倍左右。所以在极力推荐在高并发程序中采用无锁编程的方式可以进一步提高程序效率。

3.1 互斥锁和读写锁

并发环境下最常用的同步手段是互斥锁和读写锁,例如pthread_mutex和pthread_readwrite_lock,常用的范式为:

void ConcurrencyOperation() {
	mutex.lock();
	// do something
	mutex.unlock();
}

这种方法的优点是:

  • 编程模型简单,如果小心控制上锁顺序,一般来说不会有死锁的问题;
  • 可以通过调节锁的粒度来调节性能。

缺点是:

  • 所有基于锁的算法都有死锁的可能;
  • 上锁和解锁时进程要从用户态切换到内核态,并可能伴随有线程的调度、上下文切换等,开销比较重;
  • 对共享数据的读与写之间会有互斥。

读写锁:写者是排他性的,一个读写锁同时只能有一个写者或多个读者(与CPU数相关),但不能同时既有读者又有写者。

在读写锁保持期间也是抢占失效的。

当读写锁是写加锁状态时, 在这个锁被解锁之前, 所有试图对这个锁加锁的线程都会被阻塞.
当读写锁在读加锁状态时, 所有试图以读模式对它进行加锁的线程都可以得到访问权, 但是如果线程希望以写模式对此锁进行加锁, 它必须直到所有的线程释放锁.
通常, 当读写锁处于读模式锁住状态时, 如果有另外线程试图以写模式加锁, 读写锁通常会阻塞随后的读模式锁请求, 这样可以避免读模式锁长期占用, 而等待的写模式锁请求长期阻塞.

3.2 无锁编程(严格来讲是非阻塞编程)

非阻塞编程可以分为lock free和wait-free两种,下面是对它们的简单描述:

lock free:锁无关,一个锁无关的程序能够确保它所有线程中至少有一个能够继续往下执行。这意味着有些线程可能会被任意的延迟,然而在每一个步骤中至少有一个线程能够执行下去。因此这个系统作为一个整体总是在前进的,尽管有些线程的进度可能没有其它线程走的快。

wait free:等待无关,一个等待无关的程序可以在有限步之内结束,而不管其它线程的相对执行速度如何。

(lock based:基于锁,基于锁的程序无法提供上面的任何保证,任一线程持有了某互斥体并处于等待状态,那么其它想要获取同意互斥体的线程只有等待,所有基于锁的算法无法摆脱死锁的阴影。)

常见的lock free编程一般是基于CAS(Compare And Swap)操作:

CAS(void *ptr, Any oldValue, Any newValue);

即查看内存地址ptr处的值,如果为oldValue则将其改为newValue,并返回true,否则返回false。

CAS特点

  • 开销较小:不需要进入内核,不需要切换线程;
  • 没有死锁:总线锁最长持续为一次read+write的时间;
  • 只有写操作需要使用CAS,读操作与串行代码完全相同,可实现读写不互斥。

缺点是:

  • 编程非常复杂,两行代码之间可能发生任何事,很多常识性的假设都不成立。
  • CAS模型覆盖的情况非常少,无法用CAS实现原子的复数操作。