初探进程和线程
之前学习过RTOS,对线程有一些认识和理解,但接触到Linux后还遇到了进程这个概念,虽然两者之间名字很相像,但其实是完全不同的两个概念。
进程包含一个内存地址和执行的线程,地址空间是进程私有的。当程序运行时,进程会为其分配资源,进程结束时,这些资源会被回收。进程之间通过IPC进行交互。线程时进程中的一条执行路径,同一个进程中的线程在同一地址空间中执行,它们彼此共享资源。
进程
进程包含线程可以运行的环境:包括内存映射、文件描述符、用户ID等。
创建进程
第一个进程是 init 进程,创建进程的 POSIX 函数是 fork( ) 。
frok 函数调用成功后有两个返回值,在子进程中返回值为0,在父进程中返回值大于0(即子进程的PID),当返回值为负时,代表调用失败。
运行不同的程序
fork 函数创建的是程序的一个副本,需要 exec 函数运行不同的程序。如果调用成功,内核将丢弃当前进程的所有资源,并将内存分配给正在加载的新程序。
进程间通信
有两种方式在进程之间传递消息。第一,将消息从一个地址空间复制到另一个地址空间(例如:FIFO,套接字和消息队列);第二,创建一个进程都可以访问的内存区域(例如:POSIX 共享内存)。
终止进程
进程可以调用 exit ( ) 自动退出,或通过接收特定信号强制退出(例如 SIGKILL 信号)。
进程终止时会有一个返回值,当进程正常终止时,返回值就是 exit 函数的参数;当是以 kill 方式终止时,返回值就是接收到信号的编号。0 表示成功,其他值表示失败。
父进程可以通过 wait( ) 或 waitpid( ) 收集返回值。如果父进程没收到返回值,将无法创建新进程。
线程
创建线程
通过函数 pthread_create( ) 创建线程, TID 为线程标识。
一个多线程进程调用 fork( ) 创建的子进程中只有调用 fork( ) 的线程,不复制所有的线程。
线程间通信
同一个进程中的线程是共享地址空间的,可以共享内存变量,不过需要通过条件变量和互斥等进行保护同步机制,而RTOS中的信号量、互斥量等就是此基础上更复杂的结构。
终止线程
线程内带调用 pthread_exit( ) ;被另一个线程调用 pthread_cancle( ) ;包含该线程的进程终止。
可以看出,线程是被包含在进程中的,不同的进程具有不同的资源,而同一进程中的不同线程是共享资源的。在 Android 中,每个应用程序就是一个独立的进程,这有利于模块化存储管理。对于多核处理器,线程又提供了并行机制。