include fileを開けません。について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
yy

include fileを開けません。について

#1

投稿記事 by yy » 18年前

 どうも、始めて利用させていただきます。プログラミング初心者のYYです。
 DxLibを解凍してウィンドウを表示するプログラムをコピー&ペーストして実行したのですが、

エラー 1 fatal error C1083: include ファイルを開けません。'DxDirectX.h': No such file or directory c:\documents and settings\○○○\my documents\visual studio 2005\projects\プロジェクト\dxlib.h 53

 とでてきてプログラムを実行できません。使用している環境はVisualStudio2005アカデミックエディションです
 何故include ファイルを開けません、と言うエラーが出てくるのでしょうか?
よろしくお願いします。

box

Re:include fileを開けません。について

#2

投稿記事 by box » 18年前

とりあえず、半角英数字だけから成るフォルダに
環境を作った方がいいのではないかと思います。

今回の「プロジェクト」のように、フォルダ名にいわゆる
全角文字を含んでいると、何かと不都合が起きることがあります。

YY

Re:include fileを開けません。について

#3

投稿記事 by YY » 18年前

 ご返答感謝します。
 まったくもって、馬鹿な間違いでした。
 DxLib.slnを開いた後で、プロジェクトを新しく作っていました。
 とりあえずこれで実行できたのですが、
 
 私はユーザー名まで全角でした

 やはり半角文字にした方が良いんでしょうか。<!--1

組木紙織

マルチスレッドでのデータの受け渡し

#4

投稿記事 by 組木紙織 » 18年前

現在windows でマルチスレッドの勉強をしています。
HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES lpThreadAttributes, // セキュリティ記述子
  DWORD dwStackSize,                        // 初期のスタックサイズ
  LPTHREAD_START_ROUTINE lpStartAddress,    // スレッドの機能
  LPVOID lpParameter,                       // スレッドの引数
  DWORD dwCreationFlags,                    // 作成オプション
  LPDWORD lpThreadId                        // スレッド識別子
);
で、スレッドにデータを渡すときにはlpParameterにスレッドに渡すデータへのポインタを渡すようになっています。
親スレッドから子スレッドをCreateThread()関数でつくり、親スレッドを破棄すると、データを静的に確保しておくと、
親スレッドを破棄したときに渡したデータが、途中で変更される可能性があると思います。
(これは正しくない表現ですが。)

親スレッドでデータを動的に確保して、データを渡すようにすると、今度は子スレッドで
渡されたデータを破棄する必要があるので、

スマートポインタのようなスレッドを関係を扱うラッパクラスを作りたいと思っているのですが、
なかなか出来ないです。(というよりどう作っていいのかが分からないです。)


このラッパクラスでしたいことは、
1,コンストラクタでスレッドを生成(スレッドに渡したいデータを引数にする)
2,デストラクタで破棄。
3,途中でスレッドの停止、再開をするメンバ関数を用意する。

と考えています。
現時点で問題なのは
上にも挙げたようにスレッドにデータを渡すときと、
スレッドの破棄をTerminateThread()使わずに(この関数は色々問題があるようなので)
することです。

かなり難しい問題なので、ヒントのようなものはいただけないでしょうか? 

Justy

Re:マルチスレッドでのデータの受け渡し

#5

投稿記事 by Justy » 18年前

 いろいろとよくわからないので、勘違いな質問があるかもしれませんが。


データを静的に確保しておくと、 親スレッドを破棄したときに
渡したデータが、途中で変更される可能性があると思います
 静的なデータなのに親スレッドを破棄時に変更される可能性がある、というのはどうケースでしょうか?
 メインスレッドが終了するときに静的なクラスのデータにおいてデストラクタが実行されて、
データが変わってしまう、という意味でしょうか?


2,デストラクタで破棄
 何を破棄しますか? データですか? スレッドですか?
 多分スレッドのことだとは思いますが、一応念のため。


スマートポインタのようなスレッドを関係
 えーと、コンストラクタとデストラクタでスレッドの生成・破棄ができるスレッドクラスを
作るのはわかりますが、そこに「スマートポインタのような」表現がつくのは
スレッドの引数として渡したデータを管理するスマートポインタのような機能も欲しい、と
いう意味でしょうか?


現時点で問題なのは 上にも挙げたようにスレッドにデータを渡す
 んーと、それぞれがデータを共有する必要がなければ渡されたデータをコピーして使えば
各スレッドでそれぞれを破棄すればよくなります。

 それができない状況なら、その親と子のスレッドとは別のもっと生存期間の長い例えばメインスレッドなどで
保持しておきます。

 あ、でもクラスをインスタンス化することで子スレッドの生成し、インスタンスの破棄でスレッドが終了するなら
子のスレッドは親のスレッドより長く生きることはないので、そのまま生のポインタを渡しても問題はないですね。


スレッドの破棄をTerminateThread()使わずにすることです
 ちゃんとスレッドの終了がシグナル状態になるのを待ってからなら問題はないですよね?
 まぁ、それでも CloseHandleの方がいいとは思いますが。

組木紙織

Re:マルチスレッドでのデータの受け渡し

#6

投稿記事 by 組木紙織 » 18年前

>静的なデータなのに親スレッドを破棄時に変更される可能性がある、というのはどうケースでしょうか?

親スレッドではなく、親スレッドの子スレッド生成関数内で静的に確保したデータという意味でした。
[/pre]
void Factory()
{
CreateThread();
return 0;
}
/*子スレッド関数*/
DWORD WINAPI ThreadFunc(LPVOID Param)
{

/*データの引渡し*/

/*色々する*/

}
[/pre]

上記のようなコードを考えた場合、Factory関数で子スレッドを生成したときに、Factory関数が
終了する前に、子スレッドでデータを引き渡せればよいのですが、確実に子スレッドにFactory関数で
静的に確保しているデータが引き渡せる保証が無いので、データを正しく引き渡せる保証がしたいということです。

>2,デストラクタで破棄
スレッドですね。
データは動的に確保していなければ関係ないので。

>>現時点で問題なのは 上にも挙げたようにスレッドにデータを渡す
> んーと、それぞれがデータを共有する必要がなければ渡されたデータをコピーして使えば

どうやってデータをコピーすればよいのか?というところで困っています。

>>スレッドの破棄をTerminateThread()使わずにすることです
> ちゃんとスレッドの終了がシグナル状態になるのを待ってからなら問題はないですよね?
そうなのですか?
というより、ミューテックスとセマフォにしかシグナル状態が無いと思っていました。
msdnには
/***********
指定したスレッドが独自のスレッドがクリティカルセクションを持っている場合、そのクリティカルセクションは解放されません。

&#8226;終了の時点でスレッドが特定の kernel32 呼び出しを実行している場合、そのスレッドが所属しているプロセスの kernel32 の状態が整合性のない状態に陥る可能性があります。

&#8226;指定したスレッドが共有 DLL のグローバル状態を操作している場合、その DLL の状態が破棄され、その DLL を使うほかのスレッドに影響を及ぼす可能性があります。
**********/
と書いており、2番目3番目がまったく意味が分からないので、TerminateThread関数は
今まで使わないようにしていました。


//マルチスレッドプログラム関係の参考書もって無いから、手元においてた方がいいのかな。
//時間かけても全然進まない。。。

Justy

Re:マルチスレッドでのデータの受け渡し

#7

投稿記事 by Justy » 18年前

親スレッドではなく、親スレッドの子スレッド生成関数内で静的に確保したデータという意味でした
 なるほど、ローカル変数で作った、というようなケースですね。
 でしたら伝わるまで待てばいいんです。
[color=#d0d0ff" face="monospace]
#include <windows.h>
#include <stdio.h>
#include <assert.h>

struct thread_proxy_data
{
    thread_proxy_data(LPTHREAD_START_ROUTINE func_, void *arg_)
    :   func(func_), arg(arg_), is_start()  {}
    LPTHREAD_START_ROUTINE  func;
    void *                  arg;
    bool                    is_start;
};


DWORD WINAPI thread_proxy(LPVOID args)
{
    thread_proxy_data *tp = reinterpret_cast<thread_proxy_data *>(args);
    tp->is_start = true;
    tp->func(tp->arg);
    return 0;
}

class Thread
{
public:
    
    Thread(LPTHREAD_START_ROUTINE start, void *arg)
    :   m_Handle(), m_Param(start, arg), m_Jointable(true)
    {
        m_Handle = CreateThread(NULL, 0,
                (LPTHREAD_START_ROUTINE)&thread_proxy, &m_Param, 0, &m_ThreadID);
        assert(m_Handle);
        while(!m_Param.is_start)
            ;
    }
    
    void join()
    {
        if(m_Jointable)
        {
            DWORD result = WaitForSingleObject(m_Handle, INFINITE);
            assert(result == WAIT_OBJECT_0);
            result = CloseHandle(m_Handle);
            assert(result);
            m_Jointable = false;
        }
    }
    
    ~Thread()
    {
        if(m_Jointable)
        {
            BOOL ret = CloseHandle(m_Handle);
            assert(ret);
        }
    }
    
private:
    thread_proxy_data   m_Param;
    HANDLE              m_Handle;
    DWORD               m_ThreadID;
    bool                m_Jointable;
};

DWORD WINAPI testA(LPVOID arg)
{
    int nmax = *reinterpret_cast<int*>(arg);
    for(int n = 1; n<=nmax; ++n)
        printf("A : %d\n", n);
    return 0;
}
DWORD WINAPI testB(LPVOID arg)
{
    int nmax = *reinterpret_cast<int*>(arg);
    for(int n = 1; n<=nmax; ++n)
        printf("B : %d\n", n);
    return 0;
}

int main(void)
{
    int argA = 5000, argB = 3000;
    {
        Thread threadA(&testA, &argA);
        Thread threadB(&testB, &argB);
        threadB.join();                    // Bの終了を待って、
    }                                      // そのまま Aを強制的に終了させる
    return 0;
}
[/color]
 
 例えばこのように汎用スレッド関数 thread_proxyを介在させることで Threadクラスのコンストラクタは
指定したスレッドが呼び出されるまで戻ってきません。
(厳密にはこのままではマズいタイミングもあるので、is_startの処理に関してはもう一工夫必要ですが)

 この延長線上で考えていけば、データをコピーするタイミングも確保できるかと思います。
 あとは、今はデストラクタはそのまま対象のスレッドを終わらせてしまっていますが、
joinを強制的に実行するようにしておけば、スレッド終了するまでデストラクタが終わらなくすることも
できます。


>>2,デストラクタで破棄
スレッドですね。
データは動的に確保していなければ関係ないので。
 なるほど。わかりました。


ミューテックスとセマフォにしかシグナル状態が無いと思っていました

WaitForSingleObject
http://msdn.microsoft.com/library/ja/jp ... frame=true
 ここにも対象のオブジェクトにはスレッドが含まれていまして、WaitForSingleObjectで
その他のオブジェクトと同様にシグナル状態をチェックできます。

組木紙織

Re:マルチスレッドでのデータの受け渡し

#8

投稿記事 by 組木紙織 » 18年前

ヒントとなるサンプルコードありがとうございます。

ざっと見ただけではちょっと良くわかりませんが、じっくり見て、自分が欲しいものに
なるように、少し手を加えようと思います。

閉鎖

“C言語何でも質問掲示板” へ戻る