pthread_kill 区别 phtread_cancel

posix的线程有两种取消模式,立即取消和延迟取消.
立即取消是你调用pthread_cancel的时候,不管线程当前正在干什么,马上被结束掉.
延迟取消是在你调用pthread_cancel以后,线程运行到一个取消点函数的时候才会结束.

你看看你线程的是不是立即取消模式啊

pthread_sercanceltype


pthread_cancel 要慎用,不到万不得已才用,退出点无法估计,

有可能动态申请了内存,而释放部分的代码没有跑到,造成内存泄漏,我就碰到过,找了好久。


另外:

sem_wait 也会有信号量丢失情况(有别windows),

如: A 线程已经给了B线程sem_post,而B不处于sem_wait状态(负载繁忙),

等运行到sem_wait时,阻塞,并没有取得信号量,用event取代更好。


别被名字吓到,pthread_kill可不是kill,而是向线程发送signal。

还记得signal吗,大部分signal的默认动作是终止进程的运行,所以,我们才要用signal()去抓信号并加上处理函数。


测试例子:


#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>
#include <signal.h>
#include <string.h>

sem_t hSemap;
pthread_t wait_thread_id;

void signal_routine(int sigNo)
{
    printf("%s(%d) signal number: %d\n",__func__,__LINE__,sigNo);
    switch( sigNo ){
        case SIGINT:
#if 1
            pthread_kill( wait_thread_id, SIGQUIT );//exit gracefully 干净退出线程
#else
            pthread_cancel( wait_thread_id );//exit dirty  不干净退出线程
#endif
            break;
    }
    return;
}

void *wait_thread(void *arg)
{
    int ret;

    printf("%s(%d)\n",__func__,__LINE__);

    while( 1 ){
        ret = sem_wait( &hSemap );
        if( ret == -1 ){
            printf("%s(%d) sem_wait error %d %s\n",__func__,__LINE__,errno,strerror(errno));
            break;
        }else if( ret == 0 ){
            printf("%s(%d) sem_wait semaphore OK\n",__func__,__LINE__);
        }
    }

    printf("%s(%d) done, thread exit gracefully!\n",__func__,__LINE__);
    return 0;
}

int main(int argc, char *argv[])
{
    int ret;
    void *thread_result;

    printf("\n\n%s(%d)\n",__func__,__LINE__);

    if( argc > 1 ){
        ret = (int)(argv[1]);
    }

    signal( SIGHUP, signal_routine );
    signal( SIGINT, signal_routine );
    signal( SIGKILL, signal_routine );
    signal( SIGQUIT, signal_routine );

    ret = sem_init( &hSemap, 0, 0 );
    if( ret == -1 ){
        printf("%s(%d) sem_init error: %d %s\n",__func__,__LINE__,errno,strerror(errno));
        goto exit;
    }

    //ret = 1/0;//Floating point exception

    ret = sem_post( &hSemap );
    if( ret == -1 ){
        printf("%s(%d) sem_post error %d %s\n",__func__,__LINE__,errno,strerror(errno));
        goto exit;
    }

#if 0
    while( 1 ){
        ret = sem_wait( &hSemap );
        if( ret == -1 ){
            printf("%s(%d) sem_wait error %d %s\n",__func__,__LINE__,errno,strerror(errno));
            break;
        }else if( ret == 0 ){
            printf("%s(%d) sem_wait semaphore OK\n",__func__,__LINE__);
        }
    }
#else
    printf("%s(%d) sem_post\n",__func__,__LINE__);
    ret = pthread_create( &wait_thread_id, NULL, wait_thread, NULL );
    if( ret == -1 ){
        printf("%s(%d) pthread_crete error %d %s\n",__func__,__LINE__,errno,strerror(errno));
        goto exit;
    }

    ret = pthread_join( wait_thread_id, &thread_result );
    if( ret == -1 ){
        printf("%s(%d) pthread_join error %d %s\n",__func__,__LINE__,errno,strerror(errno));
        goto exit;
    }
#endif

exit:
    sem_destroy( &hSemap );
    printf("%s(%d) sem_destroy\n",__func__,__LINE__);
    return 0;
}


你可能感兴趣的:(pthread_kill 区别 phtread_cancel)