0

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

VC:

#include <pthread.h>

void V() {
    pthread_exit(0);
}

対:

.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 に答える