DXライブラリ関数はスレッドフリーでしょうか?

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

DXライブラリ関数はスレッドフリーでしょうか?

#1

投稿記事 by yoshihingis » 13年前

お世話になります。
C言語 & DirectX初心者です。
質問ですが、DXライブラリの関数はスレッドフリーでしょうか?

[やりたいこと]
4CoreのCPUを使用して、4段のパイプライン処理を実現したい。
画像データをパイプラインで引き渡してゆき、各Coreで表示位置を変えて画面上に表示する。
画像は720X480 8bitX3CHのカラー画像でデータはRGBの順に並んでいる
test0000.raw 全面赤色
test0001.raw 全面黄色
test0002.raw 全面青色
test0003.raw 全面緑色
4枚の画像を逐次Readしては、ImageXにSetし、描画し、次のパイプラインに引き渡す。
READ用,WRITE用のメモリバッファはダブルバッファとして、READ中のメモリのWRITE,
WRITE中のメモリのREADはしないようにする。

ということで下記のようなコードを作ってみました。
一応、所定の動作はしているのですが、気になるのは、329行目-349行目の

// グラフィックハンドル作成&描画(Core0)
grhandle1 = CreateGraphFromSoftImage( handle1 ) ;
DrawGraph( 0, 0, grhandle1, TRUE ) ;

// グラフィックハンドル作成&描画(Core1)
grhandle2 = CreateGraphFromSoftImage( handle2 ) ;
DrawGraph( xoffset ,0, grhandle2, TRUE ) ;


// グラフィックハンドル作成&描画(Core2)
grhandle3 = CreateGraphFromSoftImage( handle3 ) ;
DrawGraph( 0 ,yoffset, grhandle3, TRUE ) ;

// グラフィックハンドル作成&描画(Core3)
grhandle4 = CreateGraphFromSoftImage( handle4 ) ;
DrawGraph(xoffset,yoffset,grhandle4,TRUE);

DrawFormatString( 0 ,0, Color, "Thread No:%d\n",n0 ) ;
  DrawFormatString( xoffset, 0 , Color, "Thread No:%d\n",n1 ) ;
  DrawFormatString( 0, yoffset , Color, "Thread No:%d\n",n2 ) ;
  DrawFormatString( xoffset, yoffset , Color, "Thread No:%d\n",n3 ) ;

の部分をOpenMPで並列化している部分で実行すると、(コメントアウトしている209,210,247,248,284,285,321,322行目で描画する。)
アクセスのエラーが生じ、プログラムが落ちます。
DXライブラリの描画関係の関数はスレッドフリーにはなっていないということでしょうか?

それともコードになにか問題がありますでしょうか?
ご教授頂ければ幸いです。

コード:

#include "DxLib.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <omp.h>


int WindowWidth = 1600;
int WindowHeight = 1200;

int LOOP;
int START = 0;
int END   = 1000;
//int END   = 0;


//int inwidth = 1500;
//int inheight = 1000;

//int inwidth = 1400;
//int inheight = 933;

//int inwidth = 1300;
//int inheight = 866;

//int inwidth = 1200;
//int inheight = 800;

//int inwidth = 1100;
//int inheight = 733;

//int inwidth = 1000;
//int inheight = 666;

int inwidth = 720;
int inheight = 480;


int xoffset = 740;
int yoffset = 500;

int Color;

int outwidth = 0;
int outheight =0;

int x,y,i,j,cno,xx=0;

int StartTime0,EndTime0,EndTime1,EndTime2,Endtime3;

int FLAG;

int n0,n1,n2,n3;

int thread_num = 1;

char ch1[512],ch2[512] ;
char st1[25],st2[25];
char c_zero[6] = "00000";
char no[10];


unsigned char* pSrc8u_1;
unsigned char* pSrc8u_A;
unsigned char* pSrc8u_B;
unsigned char* pSrc8u_C;
unsigned char* pSrc8u_D;
unsigned char* pSrc8u_E;
unsigned char* pSrc8u_F;


unsigned char* image1;
unsigned char* image2;
unsigned char* image3;
unsigned char* image4;




FILE *fp1;


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	int handle1,handle2,handle3,handle4 ;
	int grhandle1,grhandle2,grhandle3,grhandle4;



	//入出力カラー画像のメモリエリア確保
    pSrc8u_1= (unsigned char*)malloc(sizeof(unsigned char)*inwidth*3*inheight);
    pSrc8u_A= (unsigned char*)malloc(sizeof(unsigned char)*inwidth*3*inheight);	
    pSrc8u_B= (unsigned char*)malloc(sizeof(unsigned char)*inwidth*3*inheight);
    pSrc8u_C= (unsigned char*)malloc(sizeof(unsigned char)*inwidth*3*inheight);
    pSrc8u_D= (unsigned char*)malloc(sizeof(unsigned char)*inwidth*3*inheight);	
    pSrc8u_E= (unsigned char*)malloc(sizeof(unsigned char)*inwidth*3*inheight);
    pSrc8u_F= (unsigned char*)malloc(sizeof(unsigned char)*inwidth*3*inheight);

	 

//LCD表示初期設定
	// DXライブラリの初期化
	if( DxLib_Init() < 0 ) return -1;

	//描画Windowsのサイズ設定
	SetGraphMode( WindowWidth , WindowHeight , 32 ) ;


	ChangeWindowMode(TRUE); // ウィンドウモードに設定

	SetDrawScreen( DX_SCREEN_BACK ); //描画先を表画面に設定

	// 空のフルカラー画像を作成する
	
	handle1 = MakeRGB8ColorSoftImage(inwidth,inheight) ;
	handle2 = MakeRGB8ColorSoftImage(inwidth,inheight) ;
	handle3 = MakeRGB8ColorSoftImage(inwidth,inheight) ;
	handle4 = MakeRGB8ColorSoftImage(inwidth,inheight) ;


	//各グラフィックハンドルの先頭アドレスを読み込む。
	image1 = ( unsigned char * )GetImageAddressSoftImage( handle1 ) ;
	image2 = ( unsigned char * )GetImageAddressSoftImage( handle2 ) ;
	image3 = ( unsigned char * )GetImageAddressSoftImage( handle3 ) ;
	image4 = ( unsigned char * )GetImageAddressSoftImage( handle4 ) ;


//*******************
//** 動画処理ループ
//*******************
for(LOOP = START;LOOP <= END;LOOP++){

	FLAG = LOOP%2 ;


//入力画像データFILE名作成

	//Input_image Read from FILE

    sprintf(no,"%d",LOOP%4);
	cno = (int)(strlen(no));

	//sprintf(st1,"%d",inwidth);
	//sprintf(st2,"%d",inheight);


	strcpy(ch1,"");
	//strcat(ch1,st1);
	//strcat(ch1,"_");
	//strcat(ch1,st2);
	//strcat(ch1,"_");
    strcat(ch1,"test");
	strncat(ch1,c_zero,4 -cno);
	strcat(ch1,no);
	strcat(ch1,".raw");

	
//Buffer確保

	//Input_image Read from FILE
		
   fp1 = fopen(ch1,"rb");
   if(fp1 == NULL){
	   printf("Input FILE Error!!\n");
	   getchar();
	   return -1;
   }
   	  
	    fread(pSrc8u_1,sizeof(unsigned char),inwidth*3*inheight,fp1);
		fclose(fp1);
	
	

//*************
//初期画面表示
//*************
	 	 
	ClearDrawScreen();//ScreenのClear

	// 白色の値を取得
	Color = GetColor( 255 , 255 , 255 ) ;


//Thread数の設定

#pragma omp parallel num_threads(4)

#pragma omp sections 
{

	//Core0処理
	#pragma omp section
	{

	n0 = omp_get_thread_num()  ;
 
	// 入力データを画面表示メモリにSetする。
	for( i = 0; i <inwidth*inheight; i++ )
	{

    		
	image1[i*3] = pSrc8u_1[i*3 + 2];
	image1[i*3+1] = pSrc8u_1[i*3 + 1];
	image1[i*3+2] = pSrc8u_1[i*3];

			
	}

	//grhandle1 = CreateGraphFromSoftImage( handle1 ) ;
	//DrawGraph( 0, 0, grhandle1, TRUE ) ;

	switch(FLAG){

		case 0:
	    	memcpy(pSrc8u_A,image1,sizeof(unsigned char)*3*inwidth*inheight);
			break;

		case 1:
			memcpy(pSrc8u_B,image1,sizeof(unsigned char)*3*inwidth*inheight);
			break;

	}

	

	}

//Core1処理	 
	#pragma omp section
	{

     n1 = omp_get_thread_num() ;

	switch(FLAG){

	case 0:
	    memcpy(image2,pSrc8u_B,sizeof(unsigned char)*3*inwidth*inheight);
		break;

	case 1:
		memcpy(image2,pSrc8u_A,sizeof(unsigned char)*3*inwidth*inheight);
		break;

	}


	//grhandle2 = CreateGraphFromSoftImage( handle2 ) ;
	//DrawGraph( xoffset ,0, grhandle2, TRUE ) ;

	switch(FLAG){

	case 0:
		 memcpy(pSrc8u_C,image2,sizeof(unsigned char)*3*inwidth*inheight);
		break;

	case 1:
		memcpy(pSrc8u_D,image2,sizeof(unsigned char)*3*inwidth*inheight);
		break;
	}

	
	}
	

//Core2処理	 
	#pragma omp section
	{

    n2 = omp_get_thread_num() ;

    DrawFormatString( 0,yoffset, Color, "Thread No:%d",omp_get_thread_num() ) ;

	switch(FLAG){

	case 0:
	    memcpy(image3,pSrc8u_D,sizeof(unsigned char)*3*inwidth*inheight);
		break;

	case 1:
		memcpy(image3,pSrc8u_C,sizeof(unsigned char)*3*inwidth*inheight);
		break;
	}

	 //grhandle3 = CreateGraphFromSoftImage( handle3 ) ;
	 //DrawGraph( 0 ,yoffset, grhandle3, TRUE ) ;

	switch(FLAG){

	case 0:
		memcpy(pSrc8u_E,image3,sizeof(unsigned char)*3*inwidth*inheight);

		break;

	case 1:
		memcpy(pSrc8u_F,image3,sizeof(unsigned char)*3*inwidth*inheight);
		break;
	}

	}


//Core3処理
	#pragma omp section
	{

    n3 = omp_get_thread_num() ;

	switch(FLAG){

	case 0:
	    memcpy(image4,pSrc8u_F,sizeof(unsigned char)*3*inwidth*inheight);

		break;

	case 1:
		memcpy(image4,pSrc8u_E,sizeof(unsigned char)*3*inwidth*inheight);

		break;
	}
	
	//grhandle4 = CreateGraphFromSoftImage( handle4 ) ;
	//DrawGraph(xoffset,yoffset,grhandle4,TRUE);

	}

}//End #pragma omp sections

	
	// グラフィックハンドル作成&描画(Core0)
	grhandle1 = CreateGraphFromSoftImage( handle1 ) ;
	DrawGraph( 0, 0, grhandle1, TRUE ) ;

	// グラフィックハンドル作成&描画(Core1)
	grhandle2 = CreateGraphFromSoftImage( handle2 ) ;
	DrawGraph( xoffset ,0, grhandle2, TRUE ) ;

	
	// グラフィックハンドル作成&描画(Core2)
	 grhandle3 = CreateGraphFromSoftImage( handle3 ) ;
	 DrawGraph( 0 ,yoffset, grhandle3, TRUE ) ;

	// グラフィックハンドル作成&描画(Core3)
	grhandle4 = CreateGraphFromSoftImage( handle4 ) ;
	DrawGraph(xoffset,yoffset,grhandle4,TRUE);

    DrawFormatString(  0 ,0, Color, "Thread No:%d\n",n0 ) ;
  DrawFormatString( xoffset, 0 , Color, "Thread No:%d\n",n1 ) ;
  DrawFormatString( 0, yoffset , Color, "Thread No:%d\n",n2 ) ;
  DrawFormatString( xoffset, yoffset , Color, "Thread No:%d\n",n3 ) ;
	
	 


	//LCD Vsync 2Wait(30FPS)
	WaitVSync(15) ;

	ScreenFlip(); //裏画面を表画面に反映

	//メモリ読み込んだ画像を消去する。
	//これを入れないと、多数の静止画を読み込んだ時、メモリが更新されなくなる。
	InitGraph() ;

}//End For

// 使い終わっったハンドルを解放
DeleteSoftImage( handle1 ) ;
DeleteSoftImage( handle2 ) ;
DeleteSoftImage( handle3 ) ;
DeleteSoftImage( handle4 ) ;


free( pSrc8u_1);
free( pSrc8u_A);
free( pSrc8u_B);
free( pSrc8u_C);
free( pSrc8u_D);
free( pSrc8u_E);
free( pSrc8u_F);



	// キー入力待ち
	WaitKey();
	

	// DXライブラリの後始末
	DxLib_End();

	// ソフトの終了
	return 0;
}



アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: DXライブラリ関数はスレッドフリーでしょうか?

#2

投稿記事 by softya(ソフト屋) » 13年前

いえ、スレッドフリーではありません。
なので、DXライブラリの関数は全て同じスレッド上で実行する必要があります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: DXライブラリ関数はスレッドフリーでしょうか?

#3

投稿記事 by みけCAT » 13年前

これを使えば、もしかしたら可能かもしれません。
http://studiokingyo.fc2web.com/dxlib/ka ... hiyou.html
8.DxLibでマルチスレッドのアプリを作りたいんだけど…
int SetMultiThreadFlag( int Flag ); この関数を使います。(DxLibプログラミング掲示板より)

説明:
DirectDraw の協調レベルをマルチスレッド対応にするかどうかをセットする
この関数に TRUE を渡して呼んでやれば協調レベルの設定時にDDSCL_MULTITHREADED を使用します。

まぁ、DirectDrawの基礎知識が無いと意味分からないかもしれませんが^^;
DirectX7以前が好きなd金魚にはかなり興味深い関数なんですが^^;
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: DXライブラリ関数はスレッドフリーでしょうか?

#4

投稿記事 by softya(ソフト屋) » 13年前

SetMultiThreadFlag(TRUE);は描画さえ避ければ大丈夫だったような。CreateGraphFromSoftImageが微妙で保証できません。
まぁ、DrawGraph関数自体はさほど重くないので分けても問題無いと思います。

【補足】プログラムコードのインデントが不適切なので読みづらい&バグの元だと思うので気をつけみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: DXライブラリ関数はスレッドフリーでしょうか?

#5

投稿記事 by h2so5 » 13年前

「スレッドフリー」という用語は初耳ですが、一般的なのでしょうか?
「スレッドフリー」「thread free」で検索してもこのページ以外の使用例が全くないのです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: DXライブラリ関数はスレッドフリーでしょうか?

#6

投稿記事 by softya(ソフト屋) » 13年前

正確にはスレッド・セーフでしょうね。何となくイメージで通じたのでそのまま書きましたが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

yoshihingis

Re: DXライブラリ関数はスレッドフリーでしょうか?

#7

投稿記事 by yoshihingis » 13年前

いろいろアドバイスありがとう「ございます。 用語の使い方の誤りまで正して頂いて恐縮です。教えて頂いた方法で試してみます。
初心者なので、なにかとお世話になると思いますが、これからもよろしくお願いいたします。

閉鎖

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