pthread_cancel 使用方法1

#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_wait(void *args){
     pthread_detach(pthread_self());
 
     pthread_mutex_lock(&g_pthread_mutex);

     printf("pthread_cond_wait_in/n");
     pthread_cond_wait(&g_pthread_cond, &g_pthread_mutex);
     printf("pthread_cond_wait_out/n");
 
     while(1) {
           printf("wait_while/n");
           sleep(1);
     }
 
     pthread_exit(NULL); 
}

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

       pthread_cond_signal(&g_pthread_cond);
       printf("pthread_cond_signal_out/n"); 

       pthread_exit(NULL); 
}

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

       pthread_mutex_unlock(&g_pthread_mutex);
       pthread_mutex_lock(&g_pthread_mutex);
       printf("pthread_mt_lock/n");
}

 

int main() {
       pthread_initialize_cond();
       pthread_initialize_mutex();
 
       if (pthread_create(&g_pthread_wait , NULL, (void * (*)(void *)) pthread_wait, NULL) !=0) {
             return FAILURE;
       }
 
       sleep(1);
       if (pthread_create(&g_pthread_signal , NULL, (void * (*)(void *)) pthread_signal, NULL) !=0) {
             return FAILURE;
       }
 
       sleep(5);
       if (pthread_create(&g_pthread_mt , NULL, (void * (*)(void *)) pthread_mt, NULL) !=0) {
            return FAILURE;
       }
 
       printf("while!/n");
       while(1);
}

 

       pthread_cancel(g_pthread_wait);的作用是将pthread_wait线程杀掉。

 

打印结果为:

pthread_cond_wait_in
pthread_cond_signal_out
pthread_cond_wait_out
wait_while
wait_while
wait_while
wait_while
wait_while
while!
pthread_cancel_in
pthread_cancel_out
pthread_mt_lock

 

如果将       pthread_mutex_unlock(&g_pthread_mutex);注释掉的话,那么就不会打印出pthread_mt_lock这条语句。

 

 

分析:

     1.pthread_wait先执行,打印pthread_cond_wait_in后,pthread_cond_wait函数被调用,等待g_pthread_cond条件,并解

                          锁;

     2.sleep 1秒后,pthread_signal执行,pthread_cond_signal函数被调用后,打印pthread_cond_signal_out,线程退出,则

                          pthread_cond_wait被唤醒,加锁之后进入while循环;

     3.sleep 5秒后,pthread_mt执行,打印pthread_cancel_in 后,调用pthread_cancel将pthread_wait线程杀掉,因为

                          pthread_cond_wait返回时,加锁了,所以pthread_wait被杀死之后,锁没有被解开,如果不调用

                          pthread_mutex_unlock解锁,下面的加锁函数就阻塞了,因此就打印不出pthread_mt_lock了。

 

补充:

被杀线程可以使用如下代码,控制本线程被杀死时的动作

       int state = 0;       int type = 0;
       pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &state);
       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &type);

pthread_setcancelstate函数

pthread_setcancelstate函数的作用是设置本线程是否允许被其他线程关闭,原型如下:

int pthread_setcancelstate(int state, int *oldstate);

参数state:可以取值PTHREAD_CANCEL_ENABLE或PTHREAD_CANCEL_DISABLE,前者表示允许被其他线程关闭,后者表示不允许,默认为前者;

参数oldstate:返回设置之前的本属性值;

返回值:0成功,非0失败;

 

pthread_setcanceltype函数

pthread_setcanceltype函数的作用是设置本线程被其他线程关闭时,以什么方式关闭,原型如下:

int pthread_setcanceltype(int type, int *oldtype);

参数type:PTHREAD_CANCEL_ASYNCHRONOUS或PTHREAD_CANCEL_DEFERRED,前者表示被立刻关闭,后者表示等线程被阻塞时再关闭,默认为后者;

参数oldtype:返回设置之前的本属性值;

返回值:0成功,非0失败;

例子:

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <pthread.h>

void *thread_function(void *arg);

int main() {

    int res;

    pthread_t a_thread;

    void *thread_result;

    res = pthread_create(&a_thread, NULL, thread_function, NULL);

    if (res != 0) {

        perror("Thread creation failed");

        exit(EXIT_FAILURE);

    }

    sleep(3);

    printf("Cancelling thread.../n");

    res = pthread_cancel(a_thread);

    if (res != 0) {

        perror("Thread cancelation failed");

        exit(EXIT_FAILURE);

    }

    printf("Waiting for thread to finish.../n");

    res = pthread_join(a_thread, &thread_result);

    if (res != 0) {

        perror("Thread join failed");

        exit(EXIT_FAILURE);

    }

    exit(EXIT_SUCCESS);

}

void *thread_function(void *arg) {

    int i, res;

    res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

    if (res != 0) {

        perror("Thread pthread_setcancelstate failed");

        exit(EXIT_FAILURE);

    }

    res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

    if (res != 0) {

        perror("Thread pthread_setcanceltype failed");

        exit(EXIT_FAILURE);

    }

    printf("thread_function is running/n");

    for(i = 0; i < 10; i++) {

        printf("Thread is still running (%d).../n", i);

        sleep(1);

    }

    pthread_exit(0);

}

运行结果:

thread_function is running

Thread is still running (0)...

Thread is still running (1)...

Thread is still running (2)...

Cancelling thread...

Waiting for thread to finish...

Thread is still running (3)...

 

pthread_cancel和pthread_join是Linux多线程编程中常用的两个函数,用于线程的终止和等待线程的结束。 pthread_cancel函数用于取消指定线程的执行,其原型为: ```c int pthread_cancel(pthread_t thread); ``` 该函数会向指定线程发送取消请求,但并不会立即终止线程的执行。被取消的线程需要在适当的时候检查取消请求,并在合适的地方调用pthread_exit函数来终止自己的执行。 pthread_join函数用于等待指定线程的结束,其原型为: ```c int pthread_join(pthread_t thread, void **retval); ``` 该函数会阻塞调用线程,直到指定的线程结束。如果指定线程已经结束,那么该函数会立即返回。通过retval参数可以获取被等待线程的返回值。 搭配使用时,通常的流程是先创建线程,然后在需要的时候调用pthread_cancel函数取消线程的执行,最后使用pthread_join函数等待线程的结束。 以下是一个示例代码: ```c #include <pthread.h> #include <stdio.h> #include <unistd.h> void* thread_func(void* arg) { printf("Thread started\n"); sleep(5); printf("Thread finished\n"); pthread_exit(NULL); } int main() { pthread_t thread; pthread_create(&thread, NULL, thread_func, NULL); sleep(2); pthread_cancel(thread); void* retval; pthread_join(thread, &retval); printf("Thread joined\n"); return 0; } ``` 在上述示例中,主线程创建了一个新线程,并在2秒后调用pthread_cancel函数取消该线程的执行。然后使用pthread_join函数等待线程的结束,并打印出"Thread joined"。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值