pthread_cancel 使用方法2

#include <pthread.h>
#include <stdio.h>

 

#define         FAILURE         0
#define         SUCCESS         1


#define         UNS32           unsigned int
#define m_ERROR(format, args...)        printf(format, ## args);//fflush(stdout);

 

static pthread_t                        g_pthread_wait;
static pthread_t                        g_pthread_signal;
static pthread_t                        g_pthread_mt;
pthread_mutex_t         g_pthread_mutex;
pthread_cond_t          g_pthread_cond;

 

UNS32 pthread_initialize_cond(void){
                if ( (pthread_cond_init(&g_pthread_cond, NULL)) != 0 ) {
                        m_ERROR("/t!!! ERROR : pthread_cond_init !!!/n");
                        return FAILURE;
                }
                return SUCCESS;
}

UNS32 pthread_initialize_mutex(void){
            if ( (pthread_mutex_init(&g_pthread_mutex, NULL)) != 0 ) {
                m_ERROR("/t!!! ERROR : pthread_mutex_init !!!/n");
                return FAILURE;
            }
                return SUCCESS;
}

/*

void pthread_cleanup(void *clean)
{

       printf("pthread_cleanup!/n");

       pthread_mutex_unlock(&g_pthread_mutex);
}

*/


void pthread_wait(void *args){
        pthread_detach(pthread_self());


        pthread_mutex_lock(&g_pthread_mutex);

 

        //pthread_cleanup_push(pthread_cleanup, NULL);

        printf("pthread_cond_wait_in /n");
        pthread_cond_wait(&g_pthread_cond, &g_pthread_mutex);

        printf("pthread_cond_wait_out /n");
        //pthread_cleanup_pop(0);

        pthread_mutex_unlock(&g_pthread_mutex);
        pthread_exit(NULL);
}

 


void pthread_signal(void *args){
        pthread_detach(pthread_self());

      

        printf("pthread_signal_lock/n");
        pthread_mutex_lock(&g_pthread_mutex);

        printf("pthread_cond_signal_in/n");
        pthread_cond_signal(&g_pthread_cond);
        printf("pthread_cond_signal_out/n");
        pthread_mutex_unlock(&g_pthread_mutex);

 

        pthread_exit(NULL);
}

 

void pthread_mt(void *args) {
        printf("pthread_cancel_in /n");
        pthread_cancel(g_pthread_wait);
        printf("pthread_cancel_out /n");
}

 

int main() {
        pthread_initialize_cond();
        pthread_initialize_mutex();

//      int sh;

        if (pthread_create(&g_pthread_wait, NULL, (void * (*)(void *)) pthread_wait, NULL) !=0) {
                return FAILURE;
        }
        sleep(1);


//      sh = pthread_mutex_trylock(&g_pthread_mutex);
//      printf("%d/n", sh);

        

        if (pthread_create(&g_pthread_mt , NULL, (void * (*)(void *)) pthread_mt, NULL) !=0) {
                return FAILURE;
        }

 

//      sh = pthread_mutex_trylock(&g_pthread_mutex);
//      printf("%d/n", sh);

 

        sleep(1);

        if (pthread_create(&g_pthread_signal , NULL, (void * (*)(void *)) pthread_signal, NULL) !=0) {
                        return FAILURE;
        }

        printf("while!/n");
        while(1);
}

 

程序执行结果为:

pthread_cond_wait_in
pthread_cancel_in
pthread_cancel_out

while!
pthread_signal_lock

 

分析如下:

1,pthread_wait线程先打印pthread_cond_wait_in ,然后执行pthread_cond_wait等待g_pthread_cond条件的到来;

2,pthread_mt线程打印pthread_cancel_in 后将ID号为g_pthread_wait的线程pthread_wait杀死后,打印

            pthread_cancel_out;

3,pthread_signal线程打印pthread_signal_lock之后,要进行加锁操作,也就阻塞在这里,不能继续执行了,

    原因如下(待考证):因为步骤2,将pthread_wait线程杀死了,而pthread_wait线程当时的状态为pthread_cond_wait解锁等

    待条件的到来,pthread_mt线程调用pthread_cancel杀掉pthread_wait时,会把pthread_cond_wait函数退出,而

    pthread_cond_wait退出时,会把g_pthread_mutex加锁,那么步骤3中进行的加锁操作就阻塞了,不能继续执行。

 

 

 

 

解决方法1:

将棕色的代码pthread_mutex_lock(&g_pthread_mutex);换成非阻塞的加锁pthread_mutex_trylock(&g_pthread_mutex);

 

解决方法2:

将红色的注释掉的代码加进来,即加入线程清楚函数。

      分析如下:

            步骤1,2同上;但是线程pthread_wait加入了清除处理机制,所以当步2将线程pthread_wait杀掉时,导致线程

                                  pthread_wait非正常退出,那么此时就会去执行pthread_cleanup_push(pthread_cleanup, NULL)函数所

                                  指定的pthread_cleanup函数,打印pthread_cleanup!,并且将g_pthread_mutex锁解开(即:释放掉因为

                                  pthread_wait线程被杀死时,pthread_cond_wait函数退出所占用的锁g_pthread_mutex

            3,pthread_signal线程打印pthread_signal_lock之后,要进行加锁操作,因为线程1被杀死的时候已经调用清除函数将锁打开

                 了,所以下面的代码可以顺利进行。

 

此时打印结果为:

pthread_cond_wait_in
pthread_cancel_in
pthread_cancel_out
pthread_cleanup!
while!
pthread_signal_lock
pthread_cond_signal_in
pthread_cond_signal_out

 

说明的是:

               1,pthread_cleanup_push与pthread_cleanup_pop函数的使用位置要灵活运用,中间只需加入线程函数代码中的容易出

                       现异常退出的代码段即可,此配对函数常用来释放掉线程自己所占用的资源。

                2,要学会利用紫色部分的pthread_mutex_trylock函数的返回值进行调试,来测试锁是否能被锁住:如果调用

                       pthread_mutex_trylock时互斥量处于未锁住状态,那么pthread_mutex_trylock将锁住互斥量,

                       不会出现阻塞并返回0,否则pthread_mutex_trylock就会失败,不能锁住互斥量,而返回EBUSY。

注意:pthread_cancel 的程序都是很“暴力的”。如果线程里面使用了内存分配,将会出现内存泄漏!!!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值