• UNIX环境高级编程 第11章 线程


    使用C++调用pthread_cleanup_push( )时,下面的代码是无法编译通过的:

    pthread_cleanup_push(cleanup, "thread 1 first handler");

    如果编译,则编译器可能会提示:no matching constructor for initialization of '__pthread_cleanup_class'。

    由于相对于C语言而言,C++对类型的要求更严格,不同的不兼容类型之间不能直接转换,比如在C++中,int *(int指针)类型和unsigned long类型就不允许直接转换,必须使用reinterpret_cast来进行类型转换,而C语言则可以使用(unsigned long)这种形式进行转换。此外,C++和const对象和非const对象也不能随意转换,从非const对象可以加上const属性转换到const对象,反之则不可以,上述代码中的"thread 1 first handler"的类型是const char *,而pthread_cleanup_push函数函数原型为:

    void pthread_cleanup_push(void (*routine)(void *), void *arg);

    其第二个参数类型为void *,无法从实参const char *类型转换到形参char *类型,因此该就没有匹配的构造函数来调用。

    解决方法是将第二个参数使用字符数组来存储,然后将数组传递给形参,数组名会自动转换到指针,如下:

    char p1[] = "thread 2 first handler";
    pthread_cleanup_push(cleanup, p1);

    至于为什么这个C语言版本的UNIX库函数调用会涉及到C++的类及构造函数,是因为该头文件检测到使用C++编译器时,就额外封装pthread_cleanup_class类,具体细节可自行查看/usr/include/pthread.h头文件。

    pthread_cleanup_push/pop函数和C++的异常处理机制之间有着未知的相互影响或者潜在的冲突,因此不要在C++中调用pthread_cleanup_push/pop函数。例如书本图11-5中的代码,使用C编译器和C++编译器编译出来的二进制程序执行结果就不相同,如下图:

    在C中,线程1没有执行清理函数,而C++中则执行了清理函数。pthread_cancel( )、pthread_cleanup_push/pop函数和C++的异常处理机制共用可能引发内存泄漏,资源丢失,程序崩溃,死锁等现象。

  • 相关阅读:
    [2020.12.5周六]Boruvka
    [2020.12.4周五] 圆上对称博弈
    [2020.12.3周四]最长上升子序列
    置顶~ 未来半年内训练计划
    cf1473d
    cf1474D
    寒假复健第一天 cf1475D
    来啦来啦,寒假复健第一题cf1475g
    12.1加训总结 2019南京
    12.7-12.13训练计划
  • 原文地址:https://www.cnblogs.com/pluse/p/6864393.html
Copyright © 2020-2023  润新知