多线程编程-监控线程.doc_第1页
多线程编程-监控线程.doc_第2页
多线程编程-监控线程.doc_第3页
多线程编程-监控线程.doc_第4页
多线程编程-监控线程.doc_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

多线程编程-监控线程1、监控线程概述12、需求13、示例14、相关文献91、监控线程概述不死线程常见于进程中的关键线程,即进程内其它线程的正常运行依赖于该线程,比如在网络编程中,负责与其它模块通信的socket线程等。如何保证关键线程始终运行,常用的方法有实现监控线程,当检测到某线程退出时,采取相应的动作,如:重启线程、重启进程、或重启整个系统。本文主要结合前面的基础,讨论如何实现监控线程、重启线程,达到不死的传说。2、需求(1) 利用多线程实现对两个线程(线程1、线程2)的监控,保证线程不死;(2) 利用信号量实现线程1、线程2的同步:先启动线程1,再启动线程2。3、示例/* * 作者: Jeffrey.zhu * 功能: 线程监控示例 * 日期: 2010年6月 * 联系方式: 墨客论文网: * CSDN博客:/gueter/ */ #include #include #include #include #include #include #include /* 线程触发标志 */enum PTHREAD_ID_NONE = -1, /* 未知状态 */ PTHREAD_ID_INIT = 0, /* 初始状态触发 */ PTHREAD_ID1 = 1, /* 线程1触发 */ PTHREAD_ID2 = 2, /* 线程2触发 */;enum PTHREAD_FLAG_ON = 1, /* 标志打开 */ PTHREAD_FLAG_OFF = 0, /* 标志关闭 */;/* 返回结果 */enum ERROR = -1, /* 失败 */ OK = 0, /* 成功 */;static int start_pthread_flag = PTHREAD_ID_INIT; /* 触发线程标志 */static int pthread1_exit_flag = PTHREAD_FLAG_ON; /* pthread1退出标志 */static int pthread2_exit_flag = PTHREAD_FLAG_ON; /* pthread2退出标志 */* 线程属性及ID */static pthread_attr_t pthreads_attr; static pthread_t tmp_id = PTHREAD_ID_INIT; static pthread_t pthread1_id = PTHREAD_ID_INIT; static pthread_t pthread2_id = PTHREAD_ID_INIT;/*快速锁,对应于上文的本地全局变量 */static pthread_mutex_t start_pthread_flag_mutex = PTHREAD_MUTEX_INITIALIZER;static pthread_mutex_t pthread1_id_mutex = PTHREAD_MUTEX_INITIALIZER;static pthread_mutex_t pthread2_id_mutex = PTHREAD_MUTEX_INITIALIZER;static pthread_mutex_t pthread1_exit_flag_mutex = PTHREAD_MUTEX_INITIALIZER;static pthread_mutex_t pthread2_exit_flag_mutex = PTHREAD_MUTEX_INITIALIZER;static int lock_var;static time_t end_time;static sem_t sem2;/* 接口声明 */static void pthread1(void *arg);static void pthread2(void *arg);static void pthread1_exit(void);static void pthread2_exit(void); static int pthreads_init(void);static void pthreads_deinit(void);/* * 作者: Jeffrey.zhu * 功能: 主线程为监控线程 * 联系方式: 墨客论文网: * CSDN博客:/gueter/ */int main(int argc, char *argv) int res; end_time = time(NULL) + 30; /* 进程运行时间:30s */ res = sem_init(&sem2, 0, 0); if (0 != res) perror(sem_init); while (time(NULL) end_time) /* 启动pthread1子线程 */ if (pthread1_exit_flag = PTHREAD_FLAG_ON) /* 判断触发者 */ if (PTHREAD_ID_INIT = start_pthread_flag) | (PTHREAD_ID1 = start_pthread_flag) pthreads_deinit(); /* 首次先deinit */ res = pthreads_init(); while (ERROR = res) /* 确保初始化成功 */ fprintf(stderr, pthread init failure, reinitn); pthreads_deinit(); res = pthreads_init(); pthread_mutex_lock(&pthread2_exit_flag_mutex); pthread2_exit_flag = PTHREAD_FLAG_ON; pthread_mutex_unlock(&pthread2_exit_flag_mutex); else start_pthread_flag = PTHREAD_ID_NONE; if (1 = pthread_equal(pthread1_id, tmp_id) /* 创建线程 */ res = pthread_create(&pthread1_id, &pthreads_attr, (void *)pthread1, NULL); if (0 != res) fprintf(stderr, Create pthread1 error:%s, reinitn, strerror(errno); if (0 = pthread_equal(pthread1_id, tmp_id) pthread_cancel(pthread1_id); pthread_mutex_lock(&pthread1_id_mutex); pthread1_id = PTHREAD_ID_INIT; pthread_mutex_unlock(&pthread1_id_mutex); pthread_mutex_lock(&pthread1_exit_flag_mutex); pthread1_exit_flag = PTHREAD_FLAG_ON; pthread_mutex_unlock(&pthread1_exit_flag_mutex); else pthread_mutex_lock(&pthread1_exit_flag_mutex); pthread1_exit_flag = PTHREAD_FLAG_OFF; pthread_mutex_unlock(&pthread1_exit_flag_mutex); /* 启动pthread2子线程 */ if (pthread2_exit_flag = PTHREAD_FLAG_ON) if (PTHREAD_ID2 = start_pthread_flag) pthreads_deinit(); res = pthreads_init(); while (ERROR = res) fprintf(stderr, pthreads init failure, reinitn); pthreads_deinit(); res = pthreads_init(); pthread_mutex_lock(&pthread1_exit_flag_mutex); pthread1_exit_flag = PTHREAD_FLAG_ON; pthread_mutex_unlock(&pthread1_exit_flag_mutex); else start_pthread_flag = PTHREAD_ID_NONE; if (1 = pthread_equal(pthread2_id, tmp_id) res = pthread_create(&pthread2_id, &pthreads_attr, (void *)pthread2, NULL); if (0 != res) fprintf(stderr, Create pthread pthread2 error:%s, reinitn, strerror(errno); if (0 = pthread_equal(pthread2_id, tmp_id) pthread_cancel(pthread2_id); pthread_mutex_lock(&pthread2_id_mutex); pthread2_id = PTHREAD_ID_INIT; pthread_mutex_unlock(&pthread2_id_mutex); else pthread_mutex_lock(&pthread2_exit_flag_mutex); pthread2_exit_flag = PTHREAD_FLAG_ON; pthread_mutex_unlock(&pthread2_exit_flag_mutex); /* end of if (0 != res) */ pthread_mutex_lock(&pthread2_exit_flag_mutex); pthread2_exit_flag = PTHREAD_FLAG_OFF; pthread_mutex_unlock(&pthread2_exit_flag_mutex); /* 监控周期 */ sleep(1); pthreads_deinit(); return 0;/* * 作者: Jeffrey.zhu * 功能: 线程函数1, 唤醒线程函数2,并自行退出 * 联系方式: 墨客论文网: * CSDN博客:/gueter/ */void pthread1(void *arg) int i; while (time(NULL) end_time) for (i=0; i2; i+) lock_var+; /* lock_var为全局变量,被两个线程共享,即锁定值 */ printf(pthread1:lock_var = %dn,lock_var); sem_post(&sem2); /* 对信号量2进行V操作,加1唤醒线程2 */ sleep(2); pthread1_exit(); /* * 作者: Jeffrey.zhu * 功能: 线程函数2, 若锁定值大于10,则自行退出 * 联系方式: 墨客论文网: * CSDN博客:/gueter/ */void pthread2(void *arg) int ret; while (time(NULL) 10) pthread2_exit(); sleep(2); /* * 作者: Jeffrey.zhu * 功能: pthread1线程退出函数 * 联系方式: 墨客论文网: * CSDN博客:/gueter/ */static void pthread1_exit(void) pthread_mutex_lock(&pthread1_exit_flag_mutex); pthread1_exit_flag = PTHREAD_FLAG_ON; pthread_mutex_unlock(&pthread1_exit_flag_mutex); /* kill掉pthread2线程,防止start_pthread_flag判断之前的竞争 */ if (0 = pthread_equal(pthread2_id, tmp_id) pthread_cancel(pthread2_id); pthread_mutex_lock(&pthread2_id_mutex); pthread2_id = PTHREAD_ID_INIT; pthread_mutex_unlock(&pthread2_id_mutex); pthread_mutex_lock(&start_pthread_flag_mutex); start_pthread_flag = PTHREAD_ID1; pthread_mutex_unlock(&start_pthread_flag_mutex); pthread_mutex_lock(&pthread1_id_mutex); pthread1_id = PTHREAD_ID_INIT; pthread_mutex_unlock(&pthread1_id_mutex); printf(pthread1 is exit!n); pthread_exit(NULL);/* * 作者: Jeffrey.zhu * 功能: pthread2线程退出函数 * 联系方式: 墨客论文网: * CSDN博客:/gueter/ */static void pthread2_exit(void) pthread_mutex_lock(&pthread2_exit_flag_mutex); pthread2_exit_flag = PTHREAD_FLAG_ON; pthread_mutex_unlock(&pthread2_exit_flag_mutex); /* kill掉pthread1线程 */ if (0 = pthread_equal(pthread1_id, tmp_id) pthread_cancel(pthread2_id); pthread_mutex_lock(&pthread1_id_mutex); pthread1_id = PTHREAD_ID_INIT; pthread_mutex_unlock(&pthread1_id_mutex); pthread_mutex_lock(&start_pthread_flag_mutex); start_pthread_flag = PTHREAD_ID2; pthread_mutex_unlock(&start_pthread_flag_mutex); pthread_mutex_lock(&pthread1_id_mutex); pthread1_id = PTHREAD_ID_INIT; pthread_mutex_unlock(&pthread1_id_mutex); printf(pthread2 is exit!n); pthread_exit(NULL);/* * 作者: Jeffrey.zhu * 功能: 初始化函数 * 联系方式: 墨客论文网: * CSDN博客:/gueter/ */static int pthreads_init(void) int opt = 1; int res; /* 互斥处理 */ res = pthread_mutex_init(&start_pthread_flag_mutex, NULL); if (0 != res) printf(pthreads_init():MUTEX INIT ERROR, reinitn); return ERROR; res = pthread_mutex_init(&pthread1_id_mutex, NULL); if (0 != res) printf(pthreads_init():MUTEX INIT ERROR, reinitn); return ERROR; res = pthread_mutex_init(&pthread2_id_mutex, NULL); if (0 != res) printf(pthreads_init():MUTEX INIT ERROR, reinitn); return ERROR; res = pthread_mutex_init(&pthread1_exit_flag_mutex, NULL); if (0 != res) printf(pthreads_init():MUTEX INIT ERROR, reinitn); return ERROR; res = pthread_mutex_init(&pthread2_exit_flag_mutex, NULL); if (0 != res) printf(pthreads_init():MUTEX INIT ERROR, reinitn); return ERROR; /* 线程属性处理 */ res = pthread_attr_init(&pthreads_attr); if (0 != res) printf(pthread_attr_init():PTHREAD ATTR INIT ERROR, reinitn); return ERROR; res = pthread_attr_setdetachstate(&pthreads_attr, PTHREAD_CREATE_DETACHED); if (0 != res) printf(pthread_attr_setdetachstate():PTHREAD ATTR SET ERROR, reinitn); return ERROR; return OK;/* * 作者: Jeffrey.zhu * 功能: 资源释放函数 * 联系方式: 墨客论文网: * CSDN博客:/gueter/ */static void pthreads_deinit(void) pthread_attr_destroy(&pthreads_attr); pthread_mutex_destroy(&start_pthread_flag_mutex); pthread_mutex_destroy(&pthread1_id_mutex); pthread_mutex_destroy(&pthread2_id_mutex); pthread_mutex_destroy(&pthread1_exit_flag_mutex); pthread_mutex_destroy(&pthread2_exit_flag_mutex);4、相关文献1、基于信号量的Linux多线程同步研究 中文摘要:信号量是进程或线程之间相互通讯的手段之一。有效地使用可以在多线程之间实现同步和互斥,以保证程序的正确的运行。在对线程的数据结构和相关的10个函数分析的基础上,以一个具体的例子给出如何使用信号量机制实现多线程之间的同步。摘自墨客论文网:/view/207

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论