pthread_cancel函数注意事项

来源:互联网 发布:sql server约束 编辑:程序博客网 时间:2024/06/05 06:19
/**************************************************相关函数:     #include <pthread.h>     int pthread_cancel(pthread_t thread)                     成功返回0,失败返回错误码**************************************************/此函数是POSIX提供的用于取消同一进程中的其它线程,此函数只发送取消请求,并不等待要取消的进程退出!线程可以选择忽略或是选择其它动作!需要注意的是:当我们调用它取消一个已经获得互斥锁/匿名信号量/写锁....但还未释放其所获得锁的线程时,如果此线程被取消,此后所有想要获得此时执行任务的线程都将处于睡眠状态,直到此锁被释放.为避免此问题的产生,我们可以调用一组函数:/**************************************************    #include <pthread.h>    void pthread_cleanup_push(void (*routine)(void *), void *arg)    void pthread_cleanup_pop(int execute)        参数解释:routine为函数指针,arg为传递给routine的参数        execute为零时,从栈中删除注册的函数,删除后将再也        不被执行。**************************************************/这两个函数被称为线程清理处理程序,类似于atexit函数,我们可以注册多个清理函数,当执行以下动作时我们所注册的函数将会回调(执行顺序与注册顺序相反):    1.线程从pthread_exit(void *)函数退出时。    2.线程响应取消请求时。    3.执行pthread_cleanup_pop函数,execute参数为非零时。这两个线程清理处理程序必须成对出现,必须处于同一作用域中,否则会编译出错。
实例:    如何使用这些函数处理以上问题!#include <stdio.h>#include <stdlib.h>#include <stdbool.h>#include <unistd.h>#include <signal.h>#include <sys/stat.h>#include <sys/types.h>#include <errno.h>#include <pthread.h>pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;void *count(void *arg){    int i=1;    while(1)    {        sleep(1);        printf("sec: %d\n", i++);    }}void handler(void *arg){    printf("[%u] is cancelled.\n", (unsigned)pthread_self());    pthread_mutex_t *pm = (pthread_mutex_t *)arg;    pthread_mutex_unlock(pm);}void *routine(void *arg){    #ifdef CLEANUP    pthread_cleanup_push(handler, (void *)&m);    #endif    pthread_mutex_lock(&m);    printf("[%u] lock the mutex!\n", (unsigned)pthread_self());    /*    ** During sleep(), if the calling thread received a cancel-    ** request and HASN'T established any cleanup handlers to    ** unlock the mutex, it will leave the mutex a DEAD-LOCK    ** state.    */    sleep(2);    printf("[%u]: job finished!\n", (unsigned)pthread_self());    pthread_mutex_unlock(&m);    printf("[%u] unlock the mutex!\n", (unsigned)pthread_self());    /*    ** NOTE:     **    ** pthread_cleanup_push() and pthread_cleanup_pop() may be    ** implemented as macro that expand to text containing '{'    ** and '}', respectively. For this reason, the caller must    ** user them pairly and ensure that they are paired within    ** a same function and at the same lexical nesting level.    */    #ifdef CLEANUP    pthread_cleanup_pop(0);    #endif    pthread_exit(NULL);}int main(int argc, char **argv){    pthread_t t, t1, t2;    pthread_create(&t, NULL, count, NULL);    pthread_create(&t1, NULL, routine, NULL);    pthread_create(&t2, NULL, routine, NULL);    printf("[%u] ==> t1\n", (unsigned)t1);    printf("[%u] ==> t2\n", (unsigned)t2);    printf("[%u] ==> main\n", (unsigned)pthread_self());    sleep(1);    pthread_cancel(t1);    pthread_cancel(t2);    sleep(2);    pthread_mutex_lock(&m);    printf("[%u] locked the mutex!\n",        (unsigned)pthread_self());    pthread_mutex_unlock(&m);    exit(0);}
原创粉丝点击