进程:
(1)进程是一个具有一定独立功能的程序的一次运行活动,同时也是资源分配的最小单元;
(2)进程是程序执行时的一个实例,即它是程序已经执行到某种程度的数据结构的汇集。
(3)从内核的观点看,进程的目的就是担当分配系统资源(CPU时间、内存等)的基本单位。
(4)Linux系统是一个多进程的系统,它的进程之间具有并行性、互不干扰等特点,每个进程都是一个独立的运行单位,拥有各自的权利和责任。其中,各个进程都运行在独立的虚拟地址空间,因此,即使一个进程发生异常,它也不会影响到系统中的其他进程。
(5)Linux中的进程包含3个段,分别为“数据段”、“代码段”和“堆栈段”。
“数据段”存放的是全局变量、常数以及动态数据分配的数据空间;
“代码段”存放的是程序代码的数据。
“堆栈段”存放的是子程序的返回地址、子程序的参数以及程序的局部变量等。
线程:
(1)线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
(2)一个进程由几个线程组成(拥有很多相对独立的执行流的用户程序共享应用程序的大部分数据结构),线程与同属一个进程的其他的线程共享进程所拥有的全部资源。通俗的说,一个进程可以有很多线程,但对于一个线程来说,它只能属于一个进程。
线程和进程的区别:
(1)"进程——资源分配的最小单位,线程——程序执行的最小单位"
(2)进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。(3)线程有自己的堆栈和局部变量,但线程没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
(4)进程有独立的地址空间,线程没有单独的地址空间(同一进程内的线程共享进程的地址空间)。
线程的优点:
1.运行于一个进程中的多个线程,它们之间使用相同的地址空间,和进程相比,它是一种非常“节俭”的多任务操作方式
2.线程间彼此切换所需的时间远远小于进程间切换所需要的时间
3.线程间方便的通信机制,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。
4.使多CPU系统更加有效
5.改善程序结构
线程的缺点:
线程比较脆弱,当一个线程崩溃,相当于整个进程崩溃;
进程的优点:
进程拥有独立的地址空间,一个进程崩溃不会对其他进程产生影响,所以多进程的程序要比多线程的程序健壮。
进程的缺点:
在进程切换时,耗费资源较大,效率要差,对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
线程的创建:
#include <pthread.h>
int pthread_create(pthread_t * tidp,const pthread_attr_t*attr,void*(*start_rtn)(void),void*arg)
参数说明:
pthread_t *restrict thread:线程号
const pthread_attr_t *restrict attr:属性、一般为NULL
void*(start_routine)(void):线程函数
void *restrict arg:arg为线程函数的形参,如果没有写NULL
因为pthread的库不是linux系统的库,所以在进行编译的时候要加上 -lpthread
终止线程:
如果进程中任何一个线程中调用exit或_exit,那么整个进程都会终止。线程的正常退出方式有:
(1) 线程从启动例程中返回
(2) 线程可以被另一个进程终止
(3) 线程自己调用pthread_exit函输
线程退出:
#include <pthread.h>
void pthread_exit(void * rval_ptr)
功能:终止调用线程
Rval_ptr:线程退出返回值的指针
线程等待:
#include <pthread.h>
int pthread_join(pthread_t tid,void **rval_ptr)
功能:阻塞调用线程,直到指定的线程终止。
Tid :等待退出的线程id
Rval_ptr:线程退出的返回值的指针
线程的取消:
一个线程取消另一个线程
int pthread_cancel(pthread_t thread);
参数说明:
pthread_t thread:进程号
取消属性(写在被取消的线程函数内)
int pthread_setcanceltype(int type, int *oldtype);
type: PTHREAD_CANCEL_DISABLE (不响应取消信号)
PTHREAD_CANCEL_ASYNCHRONOUS (立即取消)
线程的分离:
线程执行后,自行释放(取代join)
int pthread_detach(pthread_t thread);
一般情况下,我们将形参写成:pthread_self(),即可将自身释放
线程同步:
线程之间对资源的竞争:
1 互斥量Mutex
2 信号灯Semaphore
3 条件变量Conditions
1、互斥量
定义互斥量(全局)、主线程中初始化(函数、宏)、访问共享资源前加锁、结束时解锁
定义互斥量:
pthread_mutex_t mutex;
初始化:
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
参数说明:
pthread_mutex_t *restrict mutex:&mutex
const pthread_mutexattr_t *restrict attr : NULL
或者使用宏定义来初始化:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
加锁:
对共享资源的访问, 要使用互斥量进行加锁, 如果互斥量已经上了锁, 调用线程会阻塞, 直到互斥量被解锁。
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
返回值: 成功则返回0, 出错则返回错误编号。
trylock是非阻塞调用模式, 如果互斥量没被锁住, trylock函数将对互斥量加锁, 并获得对共享资源的访问权限; 如果互斥量被锁住了,trylock函数将不会阻塞等待而直接返回EBUSY, 表示共享资源处于忙状态
解锁:
int pthread_mutex_unlock(pthread_mutex_t *mutex);