Chinaunix首页 | 论坛 | 博客
  • 博客访问: 329521
  • 博文数量: 57
  • 博客积分: 146
  • 博客等级: 入伍新兵
  • 技术积分: 769
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-29 14:57
文章分类
文章存档

2014年(39)

2013年(13)

2012年(5)

我的朋友

分类: C/C++

2014-04-02 15:00:43

#include
int pthread_kill(pthread_t thread, int sig);
pthead_kill作用:发送信号给某线程(线程对信号进行处理检测某线程是否存活(参数sig指定为0)

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <pthread.h>
  4. #include <signal.h>


  5. static int a = 10;
  6. pthread_mutex_t glock = PTHREAD_MUTEX_INITIALIZER;

  7. static void sig_hdl(int signum)
  8. {
  9.      if(signum == SIGQUIT){
  10.          printf("SIGQUIT received\n");
  11.          pthread_exit(NULL);
  12.      }
  13.      else{
  14.          printf("signal %d received\n", signum);
  15.      }

  16.      return;
  17. }

  18. void *do_w(void *args)
  19. {
  20.     struct sigaction sa_usr;
  21.     sa_usr.sa_flags = 0;
  22.     sa_usr.sa_handler = sig_hdl;
  23.     sigaction(SIGQUIT, &sa_usr, NULL);

  24.     do{
  25.         pthread_mutex_lock(&glock);
  26.         a++;
  27.         sleep(5);
  28.         pthread_mutex_unlock(&glock);
  29.         sleep(1);
  30.     }while(1);

  31.     return NULL;
  32. }

  33. void *do_r(void *args)
  34. {
  35.     do{
  36.         pthread_mutex_lock(&glock);
  37.         printf("read a : %d\n", a);
  38.         pthread_mutex_unlock(&glock);
  39.         sleep(1);
  40.     }while(1);

  41.     return;
  42. }

  43. void main(void)
  44. {
  45.     pthread_t wid, rid;
  46.     pthread_create(&rid, NULL, do_r, NULL);
  47.     pthread_create(&wid, NULL, do_w, NULL);

  48.     do{
  49.         if (a > 13){
  50.             pthread_kill(wid, SIGQUIT);
  51.             break;
  52.         }
  53.     }while(1);

  54.     pthread_join(rid, NULL);
  55.     pthread_join(wid, NULL);

  56.     return;
  57. }
当主线程通过pthread_kill发送SIGQUIT信号给do_w线程,该信号的处理函数会调用pthread_exit线程退出。
若do_w线程在lock后unlock前收到SIGQUIT信号,则锁资源就没有释放,线程do_r就会堵塞无法继续执行。

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

下面的代码,在do_w线程中加入了pthread_cleanup_push/pthread_cleanup_pop函数,用来解决线程退出时自动释放资源。

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <pthread.h>
  4. #include <signal.h>


  5. static int a = 10;
  6. pthread_mutex_t glock = PTHREAD_MUTEX_INITIALIZER;

  7. static void sig_hdl(int signum)
  8. {
  9.      if(signum == SIGQUIT){
  10.          printf("SIGQUIT received\n");
  11.          pthread_exit(NULL);
  12.      }
  13.      else{
  14.          printf("signal %d received\n", signum);
  15.      }

  16.      return;
  17. }

  18. void *do_w(void *args)
  19. {
  20.     struct sigaction sa_usr;
  21.     sa_usr.sa_flags = 0;
  22.     sa_usr.sa_handler = sig_hdl; //信号处理函数

  23.     sigaction(SIGQUIT, &sa_usr, NULL);
  24.     pthread_cleanup_push(pthread_mutex_unlock, (void *)&glock);
  25.     do{
  26.         pthread_mutex_lock(&glock);
  27.         a++;
  28.         sleep(5);
  29.         pthread_mutex_unlock(&glock);
  30.         sleep(1);
  31.     }while(1);
  32.     pthread_cleanup_pop(0);

  33.     return NULL;
  34. }

  35. void *do_r(void *args)
  36. {
  37.     do{
  38.         pthread_mutex_lock(&glock);
  39.         printf("read a : %d\n", a);
  40.         pthread_mutex_unlock(&glock);
  41.         sleep(1);
  42.     }while(1);

  43.     return;
  44. }

  45. void main(void)
  46. {
  47.     pthread_t wid, rid;
  48.     pthread_create(&rid, NULL, do_r, NULL);
  49.     pthread_create(&wid, NULL, do_w, NULL);

  50.     do{
  51.         if (a > 13){
  52.             pthread_kill(wid, SIGQUIT);
  53.             break;
  54.         }
  55.     }while(1);

  56.     pthread_join(rid, NULL);
  57.     pthread_join(wid, NULL);

  58.     return;
  59. }




阅读(2701) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~