2011-02-09 2 views
0

私はオペレーティングシステムコースの紹介をしています。私たちはLinuxでclone()呼び出しを使ってスレッドを作成してから、いくつかのことをします。私はちょうどクローン()を使うだけで問題があるようです。クラスと名前空間の中でlinuxでどのようにクローン()をしますか?

私はクラス(コース)の名​​前空間である(宿題と呼ばれる)単一のクラスに私のコードを構造化しました。これは私が実際にnamespaceキーワードを使用した初めてのので、これが問題になる可能性があります。私はめったにそれを経験しないようにすることをめざしているので、私が間違ったミスを犯すならば、それをしてください。

ウェブ上でいくつかの記事を見つけましたが、あまり役に立たなかったです。私はマニュアルページを読んだことがありますが、問題の内容を理解するのに十分な経験はないと思います。ある日!どのような援助:)

ためのおかげで、私はクラス内のクローンをキャッチする方法を持つようにしたい:

// -- Header -- // 
namespace _Course_ { 
    class _Homework_ { 
       ... 
     int threadCatch(void *); 
       ... 
    }; 
} 

// -- Source -- // 
namespace _Course_ { 
    void _Homework_::threadTest(void) { 
      ... 
    // From web article 
    void **childStack; 
    childStack = (void **) malloc(KILOBYTE); 
    clone(threadCatch, childStack, CLONE_VM | CLONE_FILES, NULL); 
      ... 
    } 

    int _Homework_::threadCatch(void *){ 
    cout << getpid() << " cloned." << endl;  
    exit(0); 
    } 
} 

は、私が現在持っているものです。私はさまざまな方法を試しました(キャッチャーをクラスから取り出して名前空間にします)。これは2回コンパイルされますが、make clean後に再コンパイルしようとすると、関数(threadCreate)が複数の場所で宣言されていることがわかります。これらの奇妙なエラーのため、私は何か間違ったことをしていると確信して、それをハックするのではなく、私はいくつかの意見を取ります。私は何をしなければならないのですか。ありがとう!

+1

質問エディタでコードを選択して "{}"ボタンをクリックするだけで、自動的にコードを書式設定できます。行く必要はありませんし、太字やイタリック体としてマークしてください。 –

+1

C++クラスと 'clone'を混ぜるのは恐ろしい考えです。 'pthread_create'ではなく' clone'を使うと、pthreadを再実装しない限り、すでにそれ自体が悪い考えです。 –

+2

C++クラスの中からclone()を呼び出しても問題ありません。関数へのポインタはすべてですそれが必要です。私は同意します。クローン()は、スレッド化されたアプリケーションを作成するときには最初の選択ではないはずです。それは、私はこのインストラクターがクローンで始まっていると思うし()、後でpthreadsに移動します。クローンから始めて、クローンよりもpthreadとその利点を理解するための基礎を学生に与えます。 –

答えて

1

キャッチ関数を静的クラス関数として定義します。また

static int threadCatch(void *); 

(そしておそらくこれは必要ありませんが、念のために、私はここでそれを言うよ)あなたも()のクローンを作成するためにそれを送信するためにスコープ解決演算子を使用する必要があるかもしれません。あなたはすでにHomeworkクラスの中で使っているので、私はそうは思わない。しかし、私はそれをちょうど言って、それはあなたを助けるかもしれない。

clone(Homework::threadCatch, childStack, CLONE_VM | CLONE_FILES, NULL); 
+0

ありがとう!私は一点でそれを静的にしていましたが、私のクラスの中にあったとは思いません。働いた(コンパイル)。ありがとうございました。 – Student

+0

ようこそ。あなたのコースに役立ち、幸運を嬉しく思っています。 –

+0

もう1つ..もし静的だったのですがクラス外であれば、Voidがextern "C"と宣言する必要があったため、おそらく動作しませんでした。 –

1

clone(2)システムコールはC linkage持つ関数へのポインタを受け取ります。あなたはC++を使っているので、threadCatch()関数をグローバル名前空間に移動し、extern "C"関数として宣言することをお勧めします。クラス内のメソッドをstaticと宣言することもできますが、Cリンケージを使用してその関数をパラメータとして渡す方法に、より密接に一致するようにしています。

あなたはそれはあなたがclone()コールへargパラメータとして、これらのオブジェクトへのポインタを渡すことができスコープの外に存在するあなたのthreadCatch()関数の内部でC++オブジェクトへの呼び出しを行う必要がある場合。 threadCatch()関数は、argを適切な型にキャストし、それに応じてC++オブジェクトにアクセスできるようにします。

+0

これはまた、私が最終的に別の壁を打つ情報を渡す必要があると確信しているので、良いアドバイスです。本当にありがとう。 – Student

+0

+1のextern "C"リンケージ。この場合、彼はそれを定義しているので、同じコンパイル単位で呼び出す必要はないことに注意してください。しかし、clone()呼び出しで期待されるように、静的関数をextern "C"として定義する方が良いです。 argをクラスへのポインタとして渡してクラスにキャストすることも良いアドバイスです。私はC関数の中で常にそれを行います。 –

関連する問題