免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1427 | 回复: 3
打印 上一主题 下一主题

[Linux] 请教一个关于线程取消的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-03-27 21:56 |只看该作者 |倒序浏览
<The linux programming interface>

Listing 32-2: Using cleanup handlers
––––––––––––––––––––––––––– ––––––––––––––––––––––– threads/thread_cleanup.c
#include <pthread.h>
#include "tlpi_hdr.h"
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static int glob = 0;             /* Predicate variable */
static void     /* Free memory pointed to by 'arg' and unlock mutex */
cleanupHandler(void *arg)
{
    int s;
    printf("cleanup: freeing block at %p\n", arg);
    free(arg);
    printf("cleanup: unlocking mutex\n");
    s = pthread_mutex_unlock(&mtx);
    if (s != 0)
        errExitEN(s, "pthread_mutex_unlock");
}
static void *
threadFunc(void *arg)
{
    int s;
    void *buf = NULL;                   /* Buffer allocated by thread */
    buf = malloc(0x10000);              /* Not a cancellation point */
    printf("thread:  allocated memory at %p\n", buf);
    s = pthread_mutex_lock(&mtx);       /* Not a cancellation point */
    if (s != 0)
        errExitEN(s, "pthread_mutex_lock");
    pthread_cleanup_push(cleanupHandler, buf);
    while (glob == 0) {
        s = pthread_cond_wait(&cond, &mtx);    /* A cancellation point */
        if (s != 0)
            errExitEN(s, "pthread_cond_wait");
    }
    printf("thread:  condition wait loop completed\n");
    pthread_cleanup_pop(1);             /* Executes cleanup handler */
    return NULL;
}
int
main(int argc, char *argv[])
{
    pthread_t thr;
    void *res;
    int s;
    s = pthread_create(&thr, NULL, threadFunc, NULL);
    if (s != 0)
        errExitEN(s, "pthread_create");
    sleep(2);                   /* Give thread a chance to get started */
    if (argc == 1) {            /* Cancel thread */
        printf("main:    about to cancel thread\n");
        s = pthread_cancel(thr);
        if (s != 0)
            errExitEN(s, "pthread_cancel");
    } else {                    /* Signal condition variable */
        printf("main:    about to signal condition variable\n");
        glob = 1;
        s = pthread_cond_signal(&cond);
        if (s != 0)
            errExitEN(s, "pthread_cond_signal");
    }
    s = pthread_join(thr, &res);
    if (s != 0)
        errExitEN(s, "pthread_join");
    if (res == PTHREAD_CANCELED)
        printf("main:    thread was canceled\n");
    else
        printf("main:    thread terminated normally\n");
    exit(EXIT_SUCCESS);
}

这段程序中, 在s = pthread_cond_wait(&cond, &mtx);    /* A cancellation point */时发生线程取消的话, 为何需要在处理函数cleanupHandler中对互斥量mtx进行解锁,
pthread_cond_wait(&cond, &mtx)在等待的时候不是已经解锁了mtk了么

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2015-03-30 13:30 |只看该作者
本帖最后由 羽剑天涯 于 2015-03-30 15:46 编辑

回复 1# qiumupo


    pthread_cond_wait这个函数调用后,会解锁传递的mutex,同时进入阻塞,等待传递的cond,(此时mutex可以被别的线程加锁,并通知cond),当cond通知收到后,会尝试重新去加锁,加锁成功后,该函数会返回,(此时mutex重新被当前线程加锁),也就是在该函数调用前和调用后,mutex都是本线程加锁状态,在该函数调用中,mutex才会处于解锁状态。
    另外,调用pthread_cancel时,如未特别指定,取消状态为PTHREAD_CANCEL_ENABLE,取消类型为PTHREAD_CANCEL_DEFERED,也就是执行了下述函数之一后采取行动:pthread_join,pthread_cond_wait,pthread_cond_timedwait,pthread_testcancel,sem_wait或sigwait。从你的线程代码中可以看到,是在pthread_con_wait结束后行动,此时已经加锁了。
    另外该线程在自己退出时也是调用cleanupHandler,这样也需要进行free和解锁。

论坛徽章:
0
3 [报告]
发表于 2015-04-13 23:49 |只看该作者
回复 2# 羽剑天涯


    是不是设置下线程分离比较好。pthread_detach().  这样线程结束时自动回收资源。。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2015-04-14 17:13 |只看该作者
回复 3# guojinshuai


    pthread_detach只是将线程设置为不需要join,回收的仅仅是线程的退出状态等一些资源,锁、条件变量等其他资源并不会自动回收(这些资源也没有直接属于该线程)……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP