Linux 多线程基本操作

典型的Linux进程同一时刻只能做一个事情,为了能够同时处理多个事情,引入了线程概念。线程的特点是:

1、 进程的所有线程共享进程的存储空间,线程间可以直接相互访问,这与进程具有独立的运行空间有显著区别。

2、 单进程可以理解为只有一个线程在运行。

3、 多线程的主要困难是线程同步问题,而没有进程的多进程通信困扰。

线程标识

进程使用pid_t数据类型标识,线程使用pthread_t数据类型标识。这是个平台相关的类型,不同实现采用不同的c数据结构对应,因此系统提供了几个可一直的线程id处理函数,如下:

   1:  #include <pthread.h>
   2:  int pthread_equal(pthread_t tpid1, pthread_t tpid2);比较两个线程id
   3:                返回值:若相等则返回非零值,否则返回零值。
   4:  pthread_t pthread_self(void);获取线程自身的线程id
   5:                返回值:调用者线程自身的线程id。

线程管理

 

线程创建:

   1:  #include <pthread.h>
   2:  int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr
   3:                 void *(*start_rtn)(void), void *restrict arg);
   4:                返回值:成功返回0,失败返回错误编号。
   5:  参数说明:
   6:  tidp——指向存储创建线程id的地址
   7:  attr——线程高级控制属性结构,后面具体描述
   8:  start_rtn——线程创建成功后执行函数,具有一个void*参数
   9:  arg——线程执行函数参数传递指针

 

线程终止:

如果进程的任一线程调用了exit、_Exit、_exit函数,那么整个进程都会终止,同时如果结束信号发送给任一线程,整个进程也会终止。

如果要终止单个线程,而不影响其它线程,可以采用的方法是:

1、线程从启动函数中返回,即start_rtn()函数执行完成时线程会终止。

2、线程调用pthread_exit()终止自己。

   1:  void  pthread_exit(void *rval_ptr);
   2:  参数rval_ptr是一个void*指针,该指针可以传递给其它线程,使用pthread_join()函数。
   3:   
   4:  int pthread_join(pthread_t thread, void **rval);
   5:  说明:
   6:  1、    调用pthread_join()的线程会阻塞,直到thread标识的线程从调用函数返回或被取消。
   7:  2、    等待的线程从调用函数start_rtn()返回时,rval的值为返回码。
   8:  3、    等待的线程被取消时,rval的值为PTHREAD_CANCELED。
   9:  4、    如果等待的线程的rval_ptr设置为NULL,调用pthread_join()的函数将等待线程退出,不获取线程终止码。

3、线程被同进程中的其它线程取消

   1:  #include <pthread.h>
   2:  int pthread_cancel(pthread_t thread);终止参数标识的线程
   3:             返回值:成功返回0,失败返回错误码。
   4:  说明:调用该函数的线程不会阻塞,它仅提出请求;thread参数标识的线程可以选择忽略终止请求。

 

线程控制与进程控制对比:

进程

线程

概述

fork

pthread_create

创建

exit

pthread_exit

退出

waitpid

pthread_join

等待其它终止

abort

pthread_cancel

中止

getpid

pthread_self

获取id

线程同步

线程没有相互间通信的困扰,各线程可以直接访问对方的数据,主要关注线程同步的措施。

1、互斥量

    互斥量声明为pthread_mutex_t类型,静态声明的互斥量可以赋值为PTHREAD_MUTEX_INITALIZER,动态声明的互斥量使用函数进行初始化。

   1:  #include <pthread.h>
   2:  int pthread_mutex_init(pthread_mutex_t *restrict mutex, constr mutex_attr_t
   3:                    *attr);
   4:  说明:参数attr置NULL,表示以默认属性初始化互斥量。
   5:  int pthread_mutex_destory(pthread_mutex_t *mutex);
   6:                  返回值:成功返回0,失败返回错误码。

操作互斥量有三个函数

   1:  int pthread_mutex_lock(pthread_mutex_t *mutex);
   2:  int pthread_mutex_trylock(pthread_mutex_t *mutex);
   3:  int pthread_mutex_unlock(pthread_mutex_t *mutex);
   4:                  返回值:成功返回0,失败范围错误码。
   5:  说明:如果不希望获取互斥量时阻塞,使用pthread_mutex_trylock()函数,当互斥量未锁时,获取互斥量锁,并返回0;否则获取锁失败,函数立即返回EBUSY。

2、读写锁

   读写锁有三种状态:读模式加锁状态,写模式加锁状态,不加锁状态。同一时刻,只有一个线程能够进入写模式加锁状态,但允许多个线程进入读模式加锁状态。

   读写锁使用pthread_rwlock_t类型变量表示,使用前必须初始化:

   1:  #include <pthread.h>
   2:  int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
   3:                     pthread_rwlockattr_t *restrict attr);
   4:  int pthread_rwlock_destory(pthread_rwlock_t *rwlock);
   5:                    返回值:成功返回0,失败返回错误码。

读写锁操作函数:

   1:  #incldue <pthread.h>
   2:  int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
   3:  int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
   4:  int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
   5:                 返回值:成功返回0,失败返回错误码。
   6:  说明:对于pthread_rwlock_rdlock()函数,可能需要检查返回值,多个获取锁可能会失败。
   7:  非阻塞版本:
   8:  int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
   9:  int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
  10:                 返回值:成功返回0,失败返回错误码。
  11:  说明:调用时若锁处于锁住状态,返回EBUSY。

上面是线程基本操作用到的接口函数,为了能够对线程进行更高级的控制,还有线程控制属性相关内容,本文只关注线程基本内容,感兴趣的读者可以自行查阅其它介绍。

posted @ 2014-03-12 13:17  ericghw  阅读(237)  评论(0编辑  收藏  举报