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

时间:2009-07-29 10:41:40

标签: c++ c pthreads

我将C ++源代码与C源代码和C ++源代码链接起来。我创建了一个带有pthread的线程,一个取消点,然后我通过C或C ++源文件调用pthread_exit。

如果pthread_exit调用来自C源,则取消处理程序不会触发!可能是什么原因?

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:

#include <pthread.h>

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

v.c:

#include <pthread.h>

void V() {
    pthread_exit(0);
}

vs.s:

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

编译

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

如果PTHREAD_EXIT是Vpp,程序会显示一条消息并终止,如果它是V或Vs则不会。

V和Vpp的反汇编是相同的,并且在V和Vpp之间更改PTHREAD_EXIT的定义仅在反汇编中的call Vcall Vpp之间变化。

编辑: 在另一台计算机上无法重现,所以我想我在库中遇到了错误。

3 个答案:

答案 0 :(得分:1)

我不知道,但您正在给予取消处理程序C ++链接。如果您也使用C链接会发生什么?

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

答案 1 :(得分:1)

在我的机器上安装的“pthread.h”头文件中 pthread_cleanup_push()函数的定义方式与C和C不同 C ++(搜索__cplusplus)。

你能尝试为f()和cleanup()提供C链接吗?

您可能会发现以上链接很有趣: http://www.cs.rit.edu/~afb/20012/cs4/slides/threads-05.html

答案 2 :(得分:0)

受到Ch的启发。 Vu-Brugier我看了pthread.h,发现我必须添加

 #undef __EXCEPTIONS

包括pthread.h之前。对于我目前的需求,这是一个令人满意的解决方法。