现在的位置: 首页 > 综合 > 正文

进程和线程的区别、进程线程的通讯+posix多线程函数

2013年01月07日 ⁄ 综合 ⁄ 共 8213字 ⁄ 字号 评论关闭

区别:      
      进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。进程和线程的区别在于:
      简而言之,一个程序至少有一个进程,一个进程至少有一个线程。
      线程的划分尺度小于进程,使得多线程程序的并发性高。
      另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
      线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行入口顺序执行序列程序出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
      从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
      进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。
      线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
      一个线程可以创建和撤销另一个线程。同一个进程中的多个线程之间可以并发执行。

      进程和线程的主要差别在于它们是不同的操作系统资源管理方式。
      进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

通讯:
      进程:  管道/FIFO/共享内存/消息队列/信号/
以上几种方式的比较:    
      1.管道:速度慢,容量有限,只有父子进程能通讯。 常见的单向进程间通信机制,发送信息的为发送进程,接受信息的为接受进程。管道通信的中间介质为文件,这样的文件为管道文件。
      2.FIFO:任何进程间都能通讯,但速度慢    
      3.消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题 。 消息队列的中间介质是消息缓冲区,消息队列最大的缺点是需要不断的复制消息。
      4.信号量:不能传递复杂消息,只能用来同步    
      5.共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存。 该方法需要有外部通信协议、同步或者互斥机制来进行配合使用才能保证通信的有效性和正确性。

      线程间同步的方法:互斥量、信号量、事件,临界区(critical section)
      临界区(critical section),保证在某一时刻只有一个线程能访问数据的简便办法。 使用临界区域的第一个忠告就是不要长时间锁住一份资源。临界区域的一个缺点就是:Critical Section不是一个核心对象,无法获知进入临界区的线程是生是死,如果进入临界区的线程挂了,没有释放临界资源,系统无法获知,而且没有办法释放该临界资源。使用临界区域的第一个忠告就是不要长时间锁住一份资源
      用事件来同步线程是最具弹性的,一个事件有激发态和非激发态。事件又分两种类型:手动重置事件和自动重置事件。一般使用自动重置事件来进行线程的同步。事件对象也可以通过通知操作的方式来保持线程的同步。并且可以实现不同进程中的线程同步操作。
      互斥量和临界区很相似,但是Mutex花费的时间比Critical section大。互斥量跟临界区很相似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共享资源都不会同时被多个线程所访问。互斥量比临界区复杂。因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享
      信号量允许多个线程同时使用共享资源,这与操作系统中的PV操作相同。它指出了同时访问共享资源的线程最大数目。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。
       Mutex是核心对象,系统级的, Event、Semaphore也是,可以跨进程使用。 只有Critical section是进程级的,也就是说他可能利用进程内的一些标志来保证该进程内的线程同步。

posix多线程函数:

pthread_create函数

pthread_create函数的作用是创建一个线程,其原型如下:

int pthread_create(pthread_t *thread,  pthread_attr_t *attr,  void *(*start_routine)(void *),  void *arg);

参数thread: 如果创建线程成功,标识本线程的唯一标识符通过本变量返回给函数调用者;

参数attr: 调用者通过该参数描述期望创建的线程具有什么样的属性,传入NULL表示使用默认属性;

参数start_routine:线程的运行实体;

参数arg: 传递给线程实体的参数;

返回值: 0成功,非0为错误码;

pthread_exit函数

pthread_exit函数的作用是结束本线程,类似于进程中的exit函数,其原型如下:

void pthread_exit(void *retval);

参数retval: 用于向其他线程传递数据;

pthread_join函数

pthread_join函数的作用是等待另外某一个线程结束,其原型如下:

int pthread_join(pthread_t th, void **thread_return);

参数th: 描述等待哪一个线程结束,其取值为pthread_create函数第一个参数的返回值;

参数thread_return:被等待线程结束时的返回值,等于pthread_exit函数的参数;

pthread_attr_init函数

pthread_attr_init函数的作用是初始化pthread_attr_t结构,用户在调用其他函数设置结构中的参数前,必须先调用本函数对结构进行初始化,其原型为:

int pthread_attr_init(pthread_attr_t *attr);

参数attr: 待初始化的pthread_attr_t结构;

返回值: 0,成功,非0,失败;

pthread_attr_destroy函数

pthread_attr_destroy函数的作用是释放pthread_attr_t结构占用的资源,pthread_attr_t结构经过初始化和其他函数设置后可能会占用某些资源,本函数的作用就是释放这些资源,一般在pthread_attr_t结构使用完毕后调用本函数,其原型为:

void pthread_attr_destroy(pthread_attr_t *attr);

参数attr: 待释放的pthread_attr_t结构;

返回值: 0,成功,非0,失败;

pthread_mutex_init函数

pthread_mutex_init函数的作用是生成一个互斥量,原型为:

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

参数mutex: 返回指向互斥量的指针;

参数mutexattr: 设置互斥量的属性,NULL表示使用默认属性,在默认属性下,系统不会检查是否存在死锁,例如同一个线程连续两次调用上锁函数就会发生死锁;

返回值: 0成功,非0失败;

pthread_mutex_lock函数

pthread_mutex_lock函数的作用是对一个互斥量上锁,原型为:

int pthread_mutex_lock(pthread_mutex_t *mutex));

参数mutex: 指向待上锁的互斥量;

返回值: 0成功,非0失败;

pthread_mutex_unlock函数

pthread_mutex_unlock函数的作用是对一个互斥量解锁,原型为:

int pthread_mutex_unlock(pthread_mutex_t *mutex);

参数mutex: 指向待解锁的互斥量;

返回值: 0成功,非0失败;

pthread_mutex_destroy函数

pthread_mutex_destroy函数的作用是释放一个互斥量,原型为:

int pthread_mutex_destroy(pthread_mutex_t *mutex);

参数mutex: 指向待释放的互斥量;

返回值: 0成功,非0失败;

pthread_attr_setdetachstate函数

pthread_attr_setdetachstate函数的作用是设置线程的detachedstate属性,可以取值PTHREAD_CREATE_JOINABLE和PTHREAD_CREATE_DETACHED,前者是默认值,表示其他线程可以使用pthread_join函数等待本线程结束,后者表示其他线程不可以对本线程使用pthread_join,其原型为:

int pthread_attr_setdetachstate(pthread_attr_t *attr, int state);

参数attr: 待设置的pthread_attr_t结构;

参数state: 取值PTHREAD_CREATE_JOINABLE或PTHREAD_CREATE_DETACHED,表示期望的属性值;

返回值: 0成功,非0失败;

pthread_attr_getdetachstate函数
pthread_attr_getdetachstate函数的作用是获取pthread_attr_t结构中的detachedstate属性,原型如下:

int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);

参数attr: 待获取属性的pthread_attr_t结构;

参数detachstate:属性的返回值;

返回值: 0成功,非0失败;

pthread_attr_setschedpolicy函数

pthread_attr_setschedpolicy函数的作用是设置schedpolicy属性,即线程调度算法。schedpolicy属性值可以是SCHED_RR、SCHED_FIFO、SCHED_OTHER,其中SCHED_RR表示轮训调度,SCHED_FIFO表示先进先出调度,SCHED_OTHER表示其他。拥有管理员权限的进程才可以创建具有SCHED_RR或SCHED_FIFO调度算法的线程,一般线程的默认调度算法都是SCHED_OTHER。函数原型为:

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

参数attr: 待设置的pthread_attr_t结构;

参数policy: 取值SCHED_RR、SCHED_FIFO或SCHED_OTHER;

返回值: 0成功,非0失败;

pthread_attr_getschedpolicy函数

pthread_attr_getschedpolicy函数的作用是获取pthread_attr_t结构中的schedpolicy属性,原型如下:

int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);

参数attr: 待获取属性的pthread_attr_t结构;

参数detachstate:属性的返回值;

返回值: 0成功,非0失败;

pthread_attr_setschedparam函数

pthread_attr_setschedparam函数的作用是设置某调度算法下的具体调度参数,原型如下:

int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);

参数attr: 待设置的pthread_attr_t结构;

参数param: 调度参数,具体参见相关手册;

返回值: 0成功,非0失败;

pthread_attr_getschedparam函数

pthread_attr_getschedparam函数的作用是获取pthread_attr_t结构中的调度参数,原型如下:

int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);

参数attr: 待获取属性的pthread_attr_t结构;

参数param: 调度参数的返回值;

返回值: 0成功,非0失败;

pthread_attr_setinheritsched函数

pthread_attr_setinheritsched函数的作用是设置线程调度算法的继承特性,可以取值PTHREAD_EXPLICIT_SCHED或PTHREAD_INHERIT_SCHED,前者表示使用结构pthread_attr_t指定的调度算法,后者表示继承父线程使用的调度算法,默认为前者,原型如下:

int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit);

参数attr: 待设置的pthread_attr_t结构;

参数policy: 取值PTHREAD_EXPLICIT_SCHED或PTHREAD_INHERIT_SCHED;

返回值: 0成功,非0失败;

pthread_attr_getinheritsched函数

pthread_attr_getinheritsched函数的作用是获取pthread_attr_t结构中的继承属性,原型如下:

int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit);

参数attr: 待获取属性的pthread_attr_t结构;

参数inherit: 继承属性的返回值;

返回值: 0成功,非0失败;

pthread_attr_setscope函数

pthread_attr_setscope函数的作用是设置线程的在什么范围内竞争CPU资源,可以取值PTHREAD_SCOPE_SYSTEM或PTHREAD_SCOPE_PROCESS,前者表示在整个系统内竞争CPU资源,后者表示在同一进程内竞争CPU资源,默认为前者,原型如下:

int pthread_attr_setscope(pthread_attr_t *attr, int scope);

参数attr: 待设置的pthread_attr_t结构;

参数policy: 取值PTHREAD_SCOPE_SYSTEM或PTHREAD_SCOPE_PROCESS;

返回值: 0成功,非0失败;

pthread_attr_getscope函数

pthread_attr_getscope函数的作用是获取pthread_attr_t结构中的CPU竞争范围属性,原型如下:

int pthread_attr_getscope(const pthread_attr_t *attr, int *scope);

参数attr: 待获取属性的pthread_attr_t结构;

参数scope: 竞争范围的返回值;

返回值: 0成功,非0失败;

设置或获取线程栈的大小

某些系统可能不支持设置或获取线程栈,只有定义了_POSIX_THREAD_ATTR_STACKSIZE宏的系统才支持上述功能,具体由两个函数提供:
pthread_attr_setstacksize函数

pthread_attr_setstacksize函数的作用是设置线程栈的大小,单位是字节,在默认情况下线程的栈是比较大的,原型如下:

int pthread_attr_setstacksize(pthread_attr_t *attr, int size);

参数attr: 待设置的pthread_attr_t结构;

参数size: 栈的大小,单位为字节;

返回值: 0成功,非0失败;

pthread_attr_getstacksize函数

pthread_attr_getstacksize函数的作用是获取pthread_attr_t结构中的栈的大小,原型如下:

int pthread_attr_getstacksize(const pthread_attr_t *attr, int *size);

参数attr: 待获取属性的pthread_attr_t结构;

参数size: 栈大小的返回值;

返回值: 0成功,非0失败;

pthread_cancel函数

pthread_cancel函数的作用是关闭另外一个线程,原型如下:

int pthread_cancel(pthread_t thread);

thread参数: 线程标识,描述关闭哪一个线程;

返回值: 0成功,非0失败;

pthread_setcancelstate函数

pthread_setcancelstate函数的作用是设置本线程是否允许被其他线程关闭,原型如下:

int pthread_setcancelstate(int state, int *oldstate);

参数state: 可以取值PTHREAD_CANCEL_ENABLE或PTHREAD_CANCEL_DISABLE,前者表示允许被其他线程关闭,后者表示不允许,默认为前者;

参数oldstate: 返回设置之前的本属性值;

返回值: 0成功,非0失败;

pthread_setcanceltype函数

pthread_setcanceltype函数的作用是设置本线程被其他线程关闭时,以什么方式关闭,原型如下:

int pthread_setcanceltype(int type, int *oldtype);

参数type: PTHREAD_CANCEL_ASYNCHRONOUS或PTHREAD_CANCEL_DEFERRED,前者表示被立刻关闭,后者表示等线程被阻塞时再关闭,默认为后者;

参数oldtype: 返回设置之前的本属性值;

返回值: 0成功,非0失败;

sem_init函数

sem_init函数的作用是生成一个旗语变量,并初始化该变量,原型为:

int sem_init(sem_t *sem, int pshared, unsigned int value);

参数sem: 返回指向旗语变量的指针;

参数pshared: 0用于本进程内,非0用于进程间,所以在线程间使用时一般设置为0;

参数value: 旗语的初始值;

返回值: 0成功,非0失败;

sem_wait函数

sem_wait函数是一个原子操作,如果旗语变量大于0,则将旗语变量减1,然后立刻返回;如果旗语变量小于等于0,则将线程阻塞,直到旗语变量大于0,原型为:

int sem_wait(sem_t * sem);

参数sem: 指向待操作的旗语变量;

返回值: 0成功,非0失败;

sem_post函数

sem_post函数也是一个原子操作,将旗语变量加1,如果旗语变量大于0,则唤醒对应的阻塞线程,原型为:

int sem_post(sem_t * sem);

参数sem: 指向待操作的旗语变量;

返回值: 0成功,非0失败;

sem_destroy函数

sem_destroy函数的作用是释放一个旗语变量,原型为:

int sem_destroy(sem_t * sem);

参数sem: 指向待释放的旗语变量;

返回值: 0成功,非0失败,如果有线程阻塞在该旗语变量上,释放函数会失败;

抱歉!评论已关闭.