进程和线程


进程与线程的关系与区别,进程之间的通信方式,线程之间的通信方式


进程

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位。

线程

线程是进程的一个实体,是CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位,线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),一个线程可以创建和撤销另一个线程。


进程与线程的关系:
  • 一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
  • 资源分配给进程,同一进程的所有线程共享该进程的所有资源。
  • 线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
  • 处理机分给线程,即真正在处理机上运行的是线程。
  • 线程是指进程内的一个执行单元,也是进程内的可调度实体。
线程与进程的区别:
  • 调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。
  • 并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可以并发执行。
  • 拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。
  • 系统开销:在创建或撤销进程的时候,由于系统都要为之分配和回收资源,导致系统开销明显大于创建或撤销线程时的开销。
    但进程有独立的地址空间,进程崩溃后, 在保护模式下不会对其他的进程产生影响,而线程只是一个进程中的不同的执行路径。
    线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个进程死掉就等于整个线程死掉
    所以多进程的程序要比多线程的程序健壮,但是在进程切换时,耗费的资源较大,效率要差些。

进程之间的通信方式:
  • 管道
  • 命名管道FIFO
  • 消息队列
  • 信号量
  • 共享存储
线程之间的通信方式:
  • 互斥锁
    互斥锁基本操作函数如下:
    功能 函数
    初始化互斥锁 pthread_mutex_init()
    阻塞申请互斥锁 pthread_mutex_lock()
    释放互斥锁 pthread_mutex_unlock()
    尝试加锁(非阻塞方式) pthread_mutex_trylock()
    销毁互斥锁 pthread_mutex_destroy()

  • 条件变量;
    条件变量的出现,可以弥补互斥锁的缺陷,有些问题仅仅靠互斥锁无法解决。但是条件变量不能单独使用,必须配合互斥锁一起实现对资源的互斥访问。
    条件变量基本操作:
    功能 函数
    初始化条件变量 pthread_cond_init()
    阻塞等待条件变量 pthread_cond_wait()
    通知等待该条件变量的第一个线程 pthread_cond_signal()
    在指定的时间之内等待条件变量 pthread_cond_timedwait()
    销毁条件变量状态 pthread_cond_destroy()

  • 读写锁;
    在对数据的读写操作时,往往是读占主要部分。为了满足当前能够允许多个读出,但只允许一个写入的需求。线程提供了读写锁来实现。读写锁基本原则如下:
    A】如果有其他线程读数据,则允许其他线程执行读操作,但是不允许写操作。
    B】如果有其他线程申请了写锁,则其他线程既不能申请读锁,也不能申请写锁
    读写锁基本操作函数如下:
    功能 函数
    初始化读写锁 pthread_rwlock_init()
    阻塞申请读锁 pthread_rwlock_rdlock()
    非阻塞申请读锁 pthread_rwlock_tryrdlock()
    阻塞申请写锁 pthread_rwlock_wrlock()
    非阻塞申请写锁 pthread_rwlock_trywrlock()
    释放锁(读锁和写锁) pthread_rwlock_unlock()
    毁坏读写锁 pthread_rwlock_destroy()

  • 线程信号
    线程是一种轻量级的进程,因此进程的信号同样适用于线程。不过相对于进程信号,线程拥有与信号相关的私有数据——线程信号掩码,则就决定了线程在信号操作时具有以下特性:
    每个线程可以先别的线程发送信号,pthread_kill()函数用来完成这一操作。
    每个线程都可以设置自己的阻塞集合。pthread_sigmask()用来完成这一操作。类似于进程中的sigprocmask()函数。主进程创建出来的线程继承主进程的掩码。
    每个线程需要设置针对某信号的处理方式,但同一个进程中对某信号的处理方式只能有一个有效,即最后一次设置的处理方式。即在所有的线程里,同一信号在任何线程里的对该信号的处理一定相同
    如果别的进程向当前进程发来一个信号,具体由哪个形成去处理,是未知的。

原文地址:https://www.cnblogs.com/newscar/p/4264140.html