c的多线程实例

 

线程特色

线程拥有本身独立的栈、调度优先级和策略、信号屏蔽字(建立时继承)、errno变量以及线程私有数据。进程的其余地址空间均被全部线程所共享,所以线程能够访问程序的全局变量和堆中分配的数据,并经过同步机制保证对数据访问的一致性。

线程建立

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

返回值:如果成功创建线程返回0,不然返回错误的编号。html

形式参数:pthread_t* thread  要建立的线程的线程id指针;
     const pthread_attr_t *restrict attr 建立线程时的线程属性;
       void *(start_rtn)(void)    返回值是void类型的指针函数;
     void *restrict arg           start_rtn的形参。
 

线程挂起

该函数的做用使得当前线程挂起,等待另外一个线程返回才继续执行。也就是说当程序运行到这个地方时,程序会先中止,而后等线程id为thread的这个线程返回,而后程序才会断续执行。
int pthread_join(pthread_t thread, void **value_ptr);
参数说明以下:thread等待退出线程的线程号;value_ptr退出线程的返回值。
返回值:若成功,则返回0;若失败,则返回错误号。
 

取消线程

    取消操做容许线程请求终止其所在进程中的任何其余线程。不但愿或不须要对一组相关的线程执行进一步操做时,能够选择执行取消操做。例如,用户请求关闭或退出正在运行的应用程序。另外一个示例是完成由许多线程执行的任务。其中的某个线程可能最终完成了该任务,而其它线程还在继续运行。因为正在运行的线程此时没有任何用处,所以取消这个线程。编程

取消点

      仅当取消操做安全时才应取消线程。pthreads标准指定了几个取消点,其中包括:安全

  •  经过pthread_testcancel调用以编程方式创建线程取消点。
  •  线程等待pthread_cond_wait或pthread_cond_timewait()中的特定条件。
  •  被sigwait(2)阻塞的函数
  •  一些标准的库调用。一般,这些调用包括线程可基于阻塞的函数。

真正的 Cancellation Points 只是在这些函数中 Cancellation Type 被修改成 PHREAD_CANCEL_ASYNCHRONOUS 和修改回 PTHREAD_CANCEL_DEFERRED 中间的一段时间。 这句话很是重要。多线程

 

线程取消

发送终止信号给thread线程,若是成功则返回0,不然为非0值。发送成功并不意味着thread会终止。异步

int pthread_cancel(pthread_t thread);

状态设置

int pthread_setcancelstate(int state, int *oldstate);

两种主要状态:函数

    PTHREAD_CANCEL_ENABLE(默认),收到cancel信号立刻设置退出状态。测试

    PTHREAD_CANCEL_DISABLE 收到cancel信号继续运行。spa

int pthread_setcanceltype(int type, int *oldtype);

 类型有两种,只有在PTHREAD_CANCEL_ENABLE状态下有效:线程

    PTHREAD_CANCEL_ASYNCHRONOUS   当即执行取消信号指针

    PTHREAD_CANCEL_DEFERRED                   运行到下一个取消点

void pthread_testcancel(void);       //放置取消点

 当stage=ENABLE && type = DEFERRED 时,pthread_testcancel()函数有效。若是在取消功能到处于禁用状态下调用pthread_testcancel(),则该函数不起做用。

请务必仅在线程取消线程操做安全的序列中插入pthread_testcancel()。除经过pthread_testcancel()调用以编程方式创建的取消点意外,pthread标准还指定了几个取消点。

测试退出点,就是测试cancel信号

 

线程终止时的清理

不管是可预见的线程终止仍是异常终止,都会存在资源释放的问题,在不考虑因运行出错而退出的前提下,如何保证线程终止时能顺利的释放掉本身所占用的资源,特别是锁资源,就是一个必须考虑解决的问题。

最常常出现的情形是资源独占锁的使用:线程为了访问临界资源而为其加上锁,但在访问过程当中被外界取消,若是线程处于响应取消状态,且采用异步方式响应,或者在打开独占锁之前的运行路径上存在取消点,则该临界资源将永远处于锁定状态得不到释放。外界取消操做是不可预见的,所以的确须要一个机制来简化用于资源释放的编程。

在POSIX线程API中提供了一个pthread_cleanup_push()/pthread_cleanup_pop()函数对用于自动释放资源--从pthread_cleanup_push()的调用点到pthread_cleanup_pop()之间的程序段中的终止动做(包括调用pthread_exit()和取消点终止)都将执行pthread_cleanup_push()所指定的清理函数。

释放资源

成对出现的一对函数,push()将清理函数送入取消清理栈(cancellation cleanup stack), pop()取出栈顶的处理程序,根据参数是否执行

void pthread_cleanup_push(void (*routine)(void*), void *arg);
void pthread_cleanup_pop(int execute);

 

线程退出

void pthread_exit(void *value_ptr);

获取当前线程id

pthread_t pthread_self(void);

 

条件锁

条件变量是利用线程间共享的全局变量进行同步的一种机制

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);

 

互斥锁的建立
通常性的互斥锁和条件锁有分静态和动态两种方式:
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);      //动态建立
int pthread_cond_destroy(pthread_cond_t *cond);
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;            //静态建立

 

建立pthread_mutex_init;销毁pthread_mutex_destroy;加锁pthread_mutex_lock;解锁pthread_mutex_unlock。
条件锁
建立pthread_cond_init;销毁pthread_cond_destroy;触发pthread_cond_signal;广播pthread_cond_broadcast;等待pthread_cond_wait。
相关文章
相关标签/搜索