• 締切済み

Rubyで書かれたプログラムに、WinAPIを組み込みたいと思っていま

Rubyで書かれたプログラムに、WinAPIを組み込みたいと思っています。 組み込む内容は、  「とある実行ファイル」に、割り当てられているCPUの数を1つにする事で、 APIに関しては、 -------------------------------------------------------- DWORD SetThreadIdealProcessor( HANDLE hThread, // スレッドのハンドル DWORD dwIdealProcessor // 理想的なプロセッサ番号 ); -------------------------------------------------------- これを組み込めば良いという事がわかりました。 しかし、分からない点が2箇所ありまして、  ・「スレッドのハンドル」  ・Rubyプログラムへの組み込み方 です。 どなたか、お分かりの方がいらっしゃいましたら、 ご教示お願いいたします。

  • Ruby
  • 回答数1
  • ありがとう数27

みんなの回答

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

ruby-mswin32だと、rubyのソースにGetCurrentThreadId()ってのがあるみたいなので、それを使って、rubyの初期化コードにSetThreadIdealProcessor()を直書きしちゃえば良いのでは。 ただ、Ruby自体(1.9まで)は基本シングルスレッドで動作しているのだから、わざわざCPUを絞る必要はないだろうし、マルチスレッドが有害ならむしろRuby側スクリプトを書き換えるほうが良いように思えます。 あるいは、コマンドStartのオプション/affinityを指定してrubyを起動するとか。

Ruby_nami
質問者

補足

ありがとうございます! 情けない話なのですが、色々と試したのですが、 rubyのソースの見方が分かりませんでした・・・。 初期化コードというのは、 initializeメソッドを使って、 プログラムの機能を初期化するあれの事で良いのでしょうか。 初心者質問で申し訳ありません。

関連するQ&A

  • Ruby(CRuby)におけるマルチスレッド処理が可能?

    Ruby(CRuby)におけるマルチスレッド処理が可能? 今、マルチコアCPUが普及しています。 その恩恵を受け、処理を分割して複数のプロセッサーで同時に実行させたいのですが、 Rubyは、こういうような複数のスレッドの同時実行をサポートしているのでしょうか?

  • マルチスレッドプログラム

    いつもお世話になっております。 今回はマルチスレッドプログラムについてお聞きしたいです。 マルチコアCPUを使ってたとえば下記のようなことをしたいときに for (int i = 0; i < 1000000; i++) { sum += i; } このまま計算するよりもいくつかスレッドを作って、計算量を分散させてから最後に足してやるほうが早いと思いまして、 現在Core2Quadが手元にありましたのでスレッドを4つ作って スレッド1で0から250000まで スレッド2で250001から500000まで スレッド3と4も同様にして実際にやってみたのですが スレッドなしの状態よりも倍くらい時間がかかってしまうようになってしまいました。 計算結果は同じになり、CPU使用率もシングル時が25%、マルチ時が100%になっているので意図したようにはできていると思います。 GetProcessAffinityMaskを使って、各スレッドにひとつづつコアを割り当てても同様でした。 実際に時間が4分の1に近くなると思っていたのですが2倍かかってしまったので不思議です。 どなたか上記のことを思惑通りに動かせそうな方法をご存知の方はご教授願います。 プログラムは全部は無理ですが重要そうなところは下記のとおりです。 スレッド作成部分 {   DWORD dwStart = ::timeGetTime();   _thread_handle[0] = (HANDLE)::_beginthreadex(NULL, 0, thread_first, NULL, CREATE_SUSPENDED, &_thread_first_id);   _thread_handle[1] = (HANDLE)::_beginthreadex(NULL, 0, thread_second, NULL, CREATE_SUSPENDED, &_thread_second_id);   _thread_handle[2] = (HANDLE)::_beginthreadex(NULL, 0, thread_third, NULL, CREATE_SUSPENDED, &_thread_third_id);   _thread_handle[3] = (HANDLE)::_beginthreadex(NULL, 0, thread_forth, NULL, CREATE_SUSPENDED, &_thread_forth_id);   for (int num = 0; num < 4; num++)   {     ::ResumeThread(_thread_handle[num]);   }   ::WaitForMultipleObjects(4, _thread_handle, TRUE, INFINITE);   for (num = 0; num < 4; num++)   {     ::CloseHandle(_thread_handle[num]);   }   DWORD dwEnd = ::timeGetTime(); } 各スレッド部分 { HANDLE hCurrent = ::GetCurrentProcess(); DWORD pamask, samask, patmp = 0; int nRet = ::SetProcessAffinityMask(hCurrent, 0x0001); ::GetProcessAffinityMask(hCurrent, &pamask, &samask); DWORD dwStart = ::timeGetTime(); _result1 = 0; for (int multi = 0; multi < _multi; multi++) {   for (DWORD i = 0; i < 100000/4; i++)   {     _result1 += i;   } } DWORD dwEnd = ::timeGetTime(); time1 = dwEnd - dwStart; ::_endthread(); return 0; } 開発環境は WindowsXP SP3 VisualStudio6.0 ATL/WTLです。

  • C++ GUIのメッセージループ。

    初心者です。 よろしくお願いします。 とても重く時間の掛かる処理を色んなサイトを参考にスレッドにしてみたんですけど、書き方が悪いのか、再描写がワンテンポ遅れたり、アプリケーションを複数起動したりするとフリーズしてしまったりします。 原因はメッセージループにあるような気がしてるんですが、この書き方はおかしいですか?? どのサイトから引用したのかわからなくなってしまいました。 気付いたことなどあったら何でもいいので教えて貰えたら嬉しいです!よろしくお願いします!! thread01に重い処理が書かれてます。 int thread_call() {   unsigned int dwThreadId[1];   HANDLE hThread[0] = (HANDLE)_beginthreadex(     NULL,     0,     ( unsigned int (__stdcall*)(void*) )thread01,     NULL,     0,     &dwThreadId[0] );   MSG msg;   DWORD dwRet = WAIT_TIMEOUT;   while ( 1 ) {     dwRet = ::MsgWaitForMultipleObjects( sL, hThread, FALSE, INFINITE, QS_ALLEVENTS );     if ( dwRet == WAIT_OBJECT_0 + sL ) {       if ( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {         ::TranslateMessage( &msg );         ::DispatchMessage( &msg );       }     } else if ( dwRet >= WAIT_OBJECT_0 && dwRet < WAIT_OBJECT_0 + sL )       break;   }   CloseHandle( hThread[0] );   hThread[0] = NULL; }

  • Rubyの実行方法について質問です。

    Rubyの実行方法について質問です。 現在windows上のコマンドプロンプトでRubyパスを 通して「ruby ファイル名」で実行する事が出来ますが、 「ファイル.rb」のrubyファイルをダブルクリックだけで 実行出来る方法があると聞いたので、 その方法をご教示願います。

  • Mutexの次の使い方で

    typedef struct{ HWND hwnd;BOOL th_end;HANDLE hmutex; } DATA, *PDATA; /////////////////////////////////////// static HANDLE hThread1,hThread2; DWORD threadID1,threadID2; static DATA data; static HANDLE hMutex; switch (msg) { case WM_CREATE: //hMutex= //CreateMutex(NULL,FALSE,NULL); data.hwnd = hWnd; data.th_end = FALSE; data.hmutex = hMutex; hThread1=CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)Thread1, (LPVOID)&data, 0,(LPDWORD)&threadID1); hThread2=CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)Thread2, (LPVOID)&data, 0,(LPDWORD)&threadID2); /*x*/hMutex= /*x*/CreateMutex(NULL,FALSE,NULL); break; とするのは正しくて/*x*/の行を削除して//をとり hMutexの位置を前に持ってくるのは間違っているのでしょうか?

  • マルチスレッドプログラミングについて

    マルチスレッドプログラミングについていくつか教えて下さい。 マルチスレッドの基礎がまだ分かってないので初心者でも分かり易いようにお願いします。 1:イベントオブジェクトについて教えて下さい。 「イベントオブジェクト」の概念がよく分かりません。 ○シグナル状態と非シグナル状態とはどういう状態なのでしょうか? ○自動リセットの場合ではどのタイミングで切り替わっているのでしょうか?(下記のソースの場合) ○手動リセットの場合ではどのタイミングで切り替えればよいのでしょうか?(下記のソースの場合) 2:CloseHandle() と ExitThread() について教えて下さい。 ○この2つの関数の役割の違いについて教えて下さい。 「スレッドハンドルを閉じる=スレッドを終了」ではないのでしょうか? また、これらの関数実行時にシグナル状態は気にする必要はありますか?(シグナル状態にしなくてよいのか?) 下記のソースは簡略化のためかなり省略されています。 DWORD WINAPI ThreadProc( DWORD i ) { while( true ) { DWORD r = WaitForMultipleObjects( 2, hEvent, FALSE, INFINITE ); if( r == WAIT_OBJECT_0 ) { // 処理1 } else if( r == WAIT_OBJECT_0 ) { // 処理2 } else { ExitThread( TRUE ); // スレッド終了 } } } void MainProc() { // 自動リセットのイベントオブジェクト作成 for( int i=0; i<2; i++ ) { hEvent[i] = CreateEvent( NULL, FALSE, FALSE, NULL ); } // スレッドを作成 hThread = CreateThread( NULL, 0, ThreadProc, NULL, 0, &dwThreadID ); }

  • スレッドの廃棄について

    ウインドウ上のボタンを押すとあるスレッドがスタートするような プログラムがあるとします。 ボタンのクリックイベントプロシージャ内で 以下のように書いてスレッドをスタートさせることにしたのですが、 Sub MainWnd_CommandButton1_Click() 'スレッドのスタート hThread1=CreateThread(ByVal 0,0,AddressOf(MainOperation),0,0,VarPtr(thread1_ID)) End Sub このままではボタンがクリックされるたびに次々新しくスレッドが 生成されてしまい収拾がつかなくなるのでは?と思います。 基本的に一つのスレッドのみを存在させたいので、 CreateThreadの直前に「CloseHandle(hThread1)」と書こうかとも 思ったのですが、仮にスレッドが存在して無い場合、その場合は 無効なハンドルをクローズすることになりそうで何だか不都合が ありそうです。 スレッドの存在を調べて、あれば安全に廃棄して新しいものをスタート させる、といったことはどのように実装するべきでしょうか? ActiveBasicを使っていますが、教えて頂く際には CやVBでも構いません。

  • windowsのプロセスIDやスレッドIDの使い道

    win32APIで取得したプロセスIDやスレッドIDの使い道について教えてください。 CreateProcessなどで取得したプロセスのハンドルやスレッドのハンドルはwin32APIで使う場面がありますが、プロセスIDやスレッドIDの使い道がわかりません。 どのような場面でプロセスIDやスレッドIDを使うのでしょうか?具体的にこんな事をするときに使うよなどあれば教えていただきたいです。 プロセスIDやスレッドIDを引数にとるAPI関数などがあれば教えていただきたいです。

  • (マルチスレッド)_beginthreadexに複数の引数を渡す

    現在プログラムでマルチスレッドをやろうとしているのですが、 マルチスレッドの関数に数値や配列などの引数を渡すことは可能でしょうか? MSDNで調べてみると、_beginthreadex関数の4番目のNULLのところに引数リストを 指定できるとあったのですが、その意味が良くわかりませんでした。 以下のプログラムの場合にマルチスレッドに変数a, b, cを引数として渡したい場合は どのように書けばいいのでしょうか? #include <stdio.h> #include <windows.h> #include <process.h> unsigned WINAPI MyThread( void *lpx ){ while (1) { printf("スレッド実行中\n"); Sleep(1000); } return 0; } void main(){ // スレッドに渡したい変数の宣言 int a = 128; int b = 256; int c = 512; // スレッドIDの宣言 DWORD thID; // マルチスレッドの開始 (HANDLE)_beginthreadex( NULL, 0, &MyThread, NULL, 0, (unsigned int*)&thID ); // ループ while (1) { printf("メイン関数実行中\n"); Sleep(2000); } }

  • プログラムを終わらせてください。

    下のプログラムが終わらなくて困っています。 終わらせる方法を教えてください。 #include <windows.h> #pragma argsused HWND hWmain; DWORD WINAPI Th(LPVOID) { char s[99]; for(unsigned i=0;i<4294967295;i++) SetWindowText(hWmain,itoa(i++,s,10)); return 0; } LONG WINAPI WinProcedure(HWND hW,UINT wM,UINT wP,LONG lP) { static HANDLE hTh; DWORD thId; DWORD ExitCode; switch(wM) { case WM_CREATE: hTh=CreateThread(0,0,Th,0,0,&thId); return 0; case WM_DESTROY: GetExitCodeThread(hTh,&ExitCode); ExitThread(ExitCode); if(hTh!=0)CloseHandle(hTh); PostQuitMessage(0); return 0; default: return(DefWindowProc(hW,wM,wP,lP)); } } WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int) { WNDCLASS wc; MSG ms; wc.lpszClassName ="Q"; wc.lpfnWndProc =(WNDPROC)WinProcedure; wc.hInstance =hI; wc.style =CS_HREDRAW|CS_VREDRAW; wc.cbClsExtra =0; wc.cbWndExtra =0; wc.hIcon =LoadIcon(hI,0); wc.hCursor =LoadCursor(0,IDC_ARROW); wc.hbrBackground =(HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName =0; RegisterClass(&wc); hWmain=CreateWindow("Q","",WS_OVERLAPPEDWINDOW,0,0,99,99,0,0,hI,0); ShowWindow(hWmain,SW_SHOW); UpdateWindow(hWmain); while(GetMessage(&ms,0,0,0)) { TranslateMessage(&ms); DispatchMessage(&ms); } return (ms.wParam); }

専門家に質問してみよう