0

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

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

抄送:

#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);
}

vc:

#include <pthread.h>

void V() {
    pthread_exit(0);
}

与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反汇编中改变。

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

4

3 回答 3

1

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

extern "C"
{
  void cleanup(void*v) { ... }
}
于 2009-07-29T10:53:34.813 回答
1

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

您能否尝试为 f() 和 cleanup() 提供 C 链接?

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

于 2009-07-29T11:23:55.003 回答
0

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

 #undef __EXCEPTIONS

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

于 2009-07-29T11:41:23.450 回答