简体   繁体   English

如果从C源而不是C ++源调用pthread_exit,取消处理程序将无法运行

[英]cancellation handler won't run if pthread_exit called from C source instead of C++ source

I'm linking a C++ source with a C source and a C++ source. 我正在将C ++源与C源和C ++源链接在一起。 I create a thread with pthread, a cancellation point and then I call pthread_exit either through the C or the C++ source file. 我使用pthread(取消点)创建了一个线程,然后通过C或C ++源文件调用pthread_exit。

If the pthread_exit call comes from the C source, the cancellation handler does not fire! 如果pthread_exit调用来自C源,则取消处理程序不会触发! What may be the reason for this? 这可能是什么原因?

b.cc: b.cc:

#include <cstdio>
#include <cstdlib>
#include <stdbool.h>
#include <pthread.h>


extern "C" void V();
extern "C" void Vpp();
extern "C" void Vs();

#define PTHREAD_EXIT Vs





void cleanup(void*v)
{
    fprintf(stderr, "Aadsfasdf\n");
    exit(0);
}


void* f(void*p)
{
    pthread_cleanup_push(cleanup, NULL);
    PTHREAD_EXIT();
    pthread_cleanup_pop(true);

    return NULL;
}

int main()
{
    pthread_t p;
    if (pthread_create(&p, NULL, f, NULL))
        abort();
    for(;;);
}

vpp.cc: vpp.cc:

#include <pthread.h>

extern "C" void Vpp();
void Vpp() {
    pthread_exit(0);
}

vc: VC:

#include <pthread.h>

void V() {
    pthread_exit(0);
}

vs.s: vs.s:

.text
Vs: .global Vs
    call pthread_exit
    spin: jmp spin

compilation with 与编译

g++ -c vpp.cc -g -o vpp.o -Wall
gcc -c v.c -g -o v.o -Wall
as vs.s -o vs.o
g++ b.cc vpp.o v.o vs.o -o b -lpthread -g -Wall

If PTHREAD_EXIT is Vpp the program displays a message and terminates, if it is V or Vs it doesn't. 如果PTHREAD_EXIT为Vpp,则程序将显示一条消息并终止,如果为V或Vs,则终止。

the disassembly for V and Vpp is identical, and changing the definition of PTHREAD_EXIT between V and Vpp merely changes between call V and call Vpp in the disassembly. V和Vpp的反汇编是相同的,并且在V和Vpp之间更改PTHREAD_EXIT的定义仅在反汇编中的call Vcall Vpp之间进行更改。

EDIT: Not reproducible on another computer, so I guess I hit an error in the library or something. 编辑:在另一台计算机上无法重现,所以我猜我在库中或其他方面遇到了错误。

I don't know, but you are giving the cancellation handler C++ linkage. 我不知道,但是您正在给取消处理程序C ++链接。 What happens if you use C linkage for that as well? 如果同时使用C链接会发生什么呢?

extern "C"
{
  void cleanup(void*v) { ... }
}

In the "pthread.h" header file installed on my machine, the pthread_cleanup_push() function is not defined the same way for C and C++ (search for __cplusplus). 在我的计算机上安装的“ pthread.h”头文件中,对于C和C ++(搜索__cplusplus),pthread_cleanup_push()函数的定义方式不同。

Could you try to give C linkage for both f() and cleanup()? 您可以尝试同时为f()和cleanup()提供C链接吗?

You may find the above link interesting: http://www.cs.rit.edu/~afb/20012/cs4/slides/threads-05.html 您可能会发现上面的链接很有趣: http : //www.cs.rit.edu/~afb/20012/cs4/slides/threads-05.html

Inspired by Ch. 受Ch。 Vu-Brugier I took a look at pthread.h and found out that I have to add Vu-Brugier,我看了看pthread.h ,发现我必须添加

 #undef __EXCEPTIONS

before including pthread.h . 在包含pthread.h之前。 This is a satisfactory workaround for my current needs. 对于我当前的需求,这是一个令人满意的解决方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM