Winodws、linux中的进程与线程

本文探讨了Linux中线程的实现方式及同步机制。通过fork、exec和clone系统调用创建新任务,并介绍了二元信号量、多元信号量、互斥量和临界区等同步手段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘自《程序员的自我修养》

 

Windows对进程和线程的实现如果教科书一般标准,Windows内核有明确的线程和进程的概念。在WindowsAPI中,可以使用明确的API:CreateProcess和CreateThread来创建进程和线程,并且有一系列的API来操作它们。但对于Linux来说,线程并不是一个通用的概念。

Linux对线程的支持颇为贫乏,事实上,在Linux内核中并不存在真正意义上的线程概念。Linux将所有的执行实体(无论是线程还是进程)都称为任务(Task),每一个任务概念上都类似于一个单线程的进程,具有内存空间、执行实体、文件资源等。不过,Linux下不同的任务之间可以选择共享内存空间,因而在实际意义上,共享了同一内存空间的多个任务构成了一个进程,这些任务也就成了进程中的线程。在Linux下,用以下方法可以创建一个新的任务:

系统调用        作用

fork              复制当前进程

exec             使用新的可执行映像覆盖当前可执行映像

clone            创建子进程并从指定位置开始执行

 

fork()函数产生一个和当前进程完全一样的新进程,并和当前进程一样从fork函数里返回。pid_t pid;

if(pid = fork())

{

    ...

}

在fork函数调用之后,新的任务将启动并和本任务一起从fork函数返回。但不同的是本任务的fork将返回新任务的pid,而新任务的fork将返回0。

fork产生新任务的速度非常快,因为fork并不复制原任务的内存空间,而是和原任务一起共享一个写时复制(Copy on Write,COW)的内存空间。所谓写时复制,指的是两个任务可以同时自由地读取内存,但任意一个任务试图对内存进行修改时,内存就会复制一份提供给修改方单独使用,以免影响到其它的任务使用。

fork只能够产生本任务的镜像,因此需要使用exec配合才能够启动别的新任务。exec可以用新的可执行映像替换当前的可执行映像,因此在fork产生了一个新任务之后,新任务可以调用exec来执行新的可执行文件。fork和exec通常用于产生新任务,而如果要产生新线程,则可以使用clone。

int clone(int (*fn)(void *), void* child_stack, int flags, void* arg);

使用clone可以产生一个新的任务,从指定的位置开始执行,并且(可选的)共享当前进程的内存空间和文件等。如此就可以在实际效果上产生一个线程。

 

 

线程安全

 

同步与锁

为了避免多个线程同时读写同一个数据而产生不可预料的后果,我们需要将各个线程对同一个数据的访问同步(Synchronization)。所谓同步,既是指在一个线程访问数据未结束的时候,其他线程不得对同一个数据进行访问。由此,对数据的访问被原子化了。

同步的最常用方法是使用(Lock)。锁是一种非强制机制,每一个线程在访问数据或资源之前首先试图获取(Acquire)锁,并在访问结束之后释放(Release)锁。在锁已经被占用的时候试图获取锁时,线程会等待,直到锁重新可用。

二元信号量(Binary Semaphore)是最简单的一种锁,它只有两种状态:占用与非占用。它适合只能被唯一一个线程独占访问的资源。挡二元信号量处于非占用状态时,第一个试图获取该二元信号量的线程会获得该锁,并将二元信号量置为占用状态,此后其它的所有试图获取该二元信号量的线程将会等待,知道该锁被释放。

对于允许多个线程并发访问的资源,多元信号量简称信号量(Semaphore),它是一个很好的选择。一个初始值未N的信号量允许N哥线程并发访问。线程访问资源的时候首先获取信号量,进行如下操作:

1.将信号量的值减1;

2.如果信号量的值小于0,则进入等待状态,否则继续执行。

访问完资源之后,线程释放信号量,进行如下操作:

1.将信号量的值加1;

2.如果信号量的值小于1,唤醒一个等待中的线程。

互斥量(Mutex)和二元信号量很类似,资源仅同时允许一个线程访问,但和信号量不同的是,信号量在整个系统可以被任何线程获取并释放,也就是说,同一个信号量可以被系统中的一个线程获取之后由另一个线程释放。而互斥量则要求哪个线程获取了互斥量,哪个线程就要负责释放这个锁,其它线程越俎代庖去释放互斥量是无效的。

临界区(Critical Section)是比互斥量更加严格的同步手段。在术语中,把临界区的锁的获取称为进入临界区,而把锁的释放称为离开临界区。临界区和互斥量与信号量的区别在于,互斥量和信号量在系统的任何进程里都是可见的,也就是说,一个进程创建了一个互斥量或信号量,另一个进程试图去获取该锁是合法的。然而,临界区的作用范围仅限于本进程,其它的进程无法获取该锁。除此之外,临界区具有和互斥量相同的性质。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值