• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:スレッドセーフでないAPIをマルチスレッドで使う)

スレッドセーフでないAPIをマルチスレッドで使う

foomufoomuの回答

  • foomufoomu
  • ベストアンサー率36% (1018/2761)
回答No.3

完全に行うのは、無理な相談なのですが、 複数のスレッドから同時に呼び出される可能性があるプログラムは、「再入可能プログラム」という作り方をしなければなりません。これは、プログラムが呼び出されるたびに、すべての変数領域、ワークファイルなどの入出力管理を新たに設定し、呼び出しプログラムごとに別の動作をし、別の価を返すことができるようになっていないといけません。 質問文にあるように、STATIC変数などを使用してはいけないわけです。 で、再入可能でないプログラムを複数のプログラムから呼び出したいとなると、「再入させない」しか、方法はありません。1つのプログラムが呼び出している間は、フラグを立てて、別のプログラムはそれが終わるまで待っているようにします。 フラグを立てる方法としては、No.1回答のようにファイルを作るというのもひとつの方法です。状況に合わせて、最適な方法を考えてください。

関連するQ&A

  • TwitterのAPI制限について

    OAuthを使ってログインしたいと思い色々調べているのですが APIの実行回数の制限についてよく分かりません。 例えば下記のコードでログイン用のURLを取得しています。 TwitterのAPIの制限が1時間に150回となっているのですが 下記のログインURL呼び出しのリクエストはAPI実行回数制限にカウントされるのか? カウントされるのであれば サーバーIP等での実行回数制限になるのか クライアントIP等での実行回数制限になるのか どちらなのでしょうか? サーバーIPでの制限であればまともにサービス展開できませんし 調べてみたのですが確認できませんでした。 ご存知の方がいらっしゃいましたらご教授下さい。 よろしくお願いします。 <? session_start(); require_once("oauth/twitteroauth/twitteroauth.php"); if($_SESSION['oauth_token']===NULL && $_SESSION['oauth_token_secret']===NULL){ $consumer_key = "xxxxxxxxxxxxxxxxxxxxxx"; $consumer_secret = "xxxxxxxxxxxxxxxxxxxxxx"; // OAuthオブジェクト生成 $to = new TwitterOAuth($consumer_key,$consumer_secret); // callbackURLを指定してRequest tokenを取得 $tok = $to->getRequestToken("http://xxxxxxxxx/callback.php"); // セッションに保存 $_SESSION['request_token']=$token=$tok['oauth_token']; $_SESSION['request_token_secret'] = $tok['oauth_token_secret']; // サインインするためのURLを取得 $url = $to->getAuthorizeURL($token); print "<a href=\"$url\">サインイン</a>"; } else{ //サインインしていればヘッダーを出力 include("user_header.php"); } ?>

    • ベストアンサー
    • PHP
  • スレッドの待機と再開

    お世話になります。 マルチスレッドのプログラムで悩んでいます。 public class ThreadLocker {  private static boolean isLocked = false;    public static void lock() {   isLocked = true;   while(isLocked) { ; }  }    public static void unlock() {   isLocked = false;  } } まず、このようなクラスを定義しました。そして複数のスレッドが ThreadLocker.lock(); を呼び出して、処理の進行をストップしている状態があるとします。この状態に対して、とある別のスレッドが ThreadLocker.unlock(); を呼び出すと、それまで無限ループしていたスレッドが解放されて処理を始める、という感じです。 この方法を試してみましたが、無限ループで何も処理をしていないとは言え、リソースを食いまくっているようで、マシンが重くなってしまいました。 そこで、スレッドの待機・再開を行う事ができる wait / notify(All?) メソッドを使用すれば良いのではないかと考えたのですが、具体的な方法が分からず、質問させていただきました。 具体的に、どのインスタンスの wait 及び notify(All?) を呼び出せば良いのかが分かりません。 APIリファレンスの「現在のスレッドはこのオブジェクトのモニターのオーナでなければなりません。」の意味もよく分かりません。 ちなみに、待機しているスレッドは複数あり、class Lock の method execute 中で ThreadLocker.lock() しているとします。 また、再開を促すスレッドは1つで、class Unlock の method execute 中で ThreadLocker.unlock() を呼び出すものとします。 そして、それぞれのスレッドは、お互いのインスタンスを知りません。(説明しづらいので、補足要求があれば、ソースで示します。) よろしくお願いいたします。

    • ベストアンサー
    • Java
  • 自動ログアウト方法を教えてください。

    現在動いているシステムに、新たに複数ログイン禁止の設定を追加したいと考えています。 それで、以下の流れでシステムを作成しようと考えています。 (1)フラグ設定用のファイルを用意して、ログインした時にファイルへフラグを立てる。 *データベースを使用できないので、ファイルを使用。 (2)フラグが立っていれば、それ以降のログインを禁止にする。 (3)フラグが立っていなければ、ログインを許可する。 *この時、ログイン情報をセッション変数に保存する。 (4)ログアウトする時に、ファイルに持たせているフラグを消去する。 *この時、ログイン情報をセッション変数から削除する。 (5)ログアウトせずに放置していた場合、一定時間を過ぎると自動でログアウトする。 ただ、この時分からない事がありまして、 「自動でログアウトする時に、フラグの削除処理とセッション変数の破棄の指示をどのようにして出すのか?」 また、 「ログアウトせずにブラウザを閉じても自動でログアウトできるのか?」 という2点に調べています。 上記2点のことでアドバイスを頂けないでしょうか? また、複数ログイン禁止の設定を行う際に、注意しておいた方がいい点などがあれば教えて頂けないでしょうか? 宜しくお願いします。

    • ベストアンサー
    • PHP
  • 株価関連情報を取得できるAPIを知りたい

    株価関連の、自分用のソフトウエアを作りたいと思っています。 そこで、株価関連情報を取得できるAPIを知りたいです。 速報性はあまり気にしません。20分ディレイとか、1日ディレイとかでもいいです。 自分なりに探してみたのですが、現時点で使えるAPIはほとんど無いように思いましたので、細かいことは言いません。 xmlとか、CSVとか、rssとか、それなりにシステム的に処理できる形で 何らかの株価関連情報を取得できるAPIをご存知でしたら、何でも良いので教えて下さい!!

  • スレッド

    VC++2008ExpressEditionを使用してプログラムを作成しています。 Windowsフォームアプリケーションを作成し、そこに、TextBoxとButtonを放り込み、ボタンを押すと以下のようなコードが実行されるようにしました。 関数testfuncはhoge::Form1::testfuncという風な場所で定義されています。 logBoxは、Form1のコンストラクタのTODOの部分で作成しています。   public: static System::Windows::Forms::TextBox^ logBox;   void testfunc(){     int i;     for(i=0;i<200;i++){       int t=clock();       while(10>clock()-t);       logBox+=L"aaraeaewa"+i+L"\r\n";       logBox->SelectionStart = logBox->Text->Length;       logBox->ScrollToCaret();     }   }   System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {     button1->Enabled=false;     button1->Text=L"実行中";     button1->Update();     ThreadStart^ trddel=gcnew ThreadStart(this,&hoge::Form1::testfunc);     Thread ^trd=gcnew Thread(trddel);     trd->Start();     button1->Enabled=true;     button1->Text=L"実行";   } この関数をボタンを押して実行すると、testfunc関数の logBox->SelectionStart = logBox->Text->Length; の部分で、 'System.InvalidOperationException' のハンドルされていない例外が System.Windows.Forms.dll で発生しました。 追加情報: 有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール 'logBox' がアクセスされました。 という風なエラーが出ます。 読んだ感じだと、元々のスレッドで作成したコントロールを新しく作ったスレッドからコントロールすることは出来ないって感じのことが書かれているのですが、どの様にすればこれは回避できるようになるのでしょうか?

  • Google static maps api と Google map api

    携帯用サイトでGoogle static maps API を使っているのですが, サイト内にテキストフォームを用意して住所を入力すると <img src="http://maps.google.com/staticmap? center=34.6663690,133.918588 ←ここを変更したい &size=250x300 &zoom=13 &maptype=mobile &key=..... > の内容を変更してその住所のマップを再表示するようにしたいと思っています. Google map APIで取得したlat, lngなどの情報を<img>内に反映させることって出来るのでしょうか?

  • wait()したスレッドが起こされるタイミング

    以下のコードにおいて。 % java ThreadWaitTest 2 の場合はaと表示したまま止まりますが、 % java ThreadWaitTest 1 の場合はスレッドの終了に伴ってwait()が切れ、bまで表示します。 私の望む動作は前者です。 後者の場合、これはつまりスレッドをwaitした際の待機プールがスレッドオブジェクトの場合、そのスレッドの実行が終了すると待機プールにある待機スレッドを自動でnotify()してしまうことを意味していると思うのですが、この解釈はあっていますか? Java のAPIドキュメントに 「別のスレッドが notify メソッドまたは notifyAll メソッドを呼び出してこのオブジェクトのモニター上で待機するスレッドに通知を出すまで待機します」 とあるように、ユーザが明確的にnotifyしないと起こらないと思いこんでいました。 なぜこういう仕様になっているのでしょうか? また、この仕様について詳しく書いてあるサイトやドキュメントなどありませんでしょうか? public class ThreadWaitTest extends Thread {  public Object mutex = new Object();    public static void main(String[] args) {   try {    ThreadWaitTest test = new ThreadWaitTest();    test.start();    System.out.println("a");    switch (new Integer(args[0])) {    case 1:     synchronized(test) {      test.wait();     }     break;    case 2:     synchronized(test.mutex) {       test.mutex.wait();     }     break;    }    System.out.println("b");   } catch (InterruptedException ie) {    ie.printStackTrace();   }  }  public void run() {   try {    Thread.sleep(5000);   } catch (InterruptedException ie){    ie.printStackTrace();}   } }

    • ベストアンサー
    • Java
  • VBでのAPI

    いつもお世話になっています。 今回初めて、APIを使うVBのプログラミングをしているんですが、サーバからのファイル名取得でつまずいています。 long型変数 = FtpFindFirstFile(セッション番号, ディレクトリパス, str型変数, 0, 0) って感じで、何かしらファイルが存在するかどうかは戻り値で判定できるのですが、ファイル名自体が取得できません。(複数ファイルが存在するときは、どれか一つのファイル名が取得できれば問題ないです) いろんなサイトを調べたのですが、「引数の文字列変数に"情報"が取得される」ようなふうに書かれており、はっきりしません。ちなみに私の作成中のPGでは、引数の文字列変数は何も格納なれない状態です。 どなたか詳しい方、教えてくれませんか?

  • ログアウトを実行してもログアウトされていない。

    こんにちは、ログアウトについてお聞きしたのですが、 どなたかお力を貸してください。 ユーザーネームとパスワードでログインする会員サイトを作っています。 会員メンバーのみ閲覧できるページがあるというシステムです。 ログインをして会員ページを閲覧できるのですが、 「ログアウトボタン」を押してもログアウト処理がされず、 まだ会員しか閲覧できないページを見ることができる状態です。 見ることができます。 いままでは、 // セッションを壊す。 //setcookie ("USERNAME", ""); //setcookie ("PASSWORD", ""); と記述していましたが、うまくいきませんでした。 調べたところ // セッション変数を全て解除する $_SESSION = array(); // セッションを切断するにはセッションクッキーも削除する。 // Note: セッション情報だけでなくセッションを破壊する。 if (isset($_COOKIE[session_name()])) { setcookie(session_name(), '', time()-42000, '/'); } // 最終的に、セッションを破壊する session_destroy(); という書き方があるとわかったのですが、 ユーザーネームとパスワードを初期化するという文法と 書き方が分からず、未だに、ログアウトできない状態です。 文法と書き方をどなたか教えて頂けないでしょうか。 また、セッションを保つ時間の記述の仕方も教えて頂けないでしょうか よろしくお願い致します。

    • 締切済み
    • PHP
  • Tomcatのスレッドを破棄する方法

    はじめまして。 使用ツール:Tomcat 6.0 前提条件:Tomcatのserver.xmlでmaxThreads="1"と記述し、同時にスレッドが1つしか動作しないようにしている 質問: ブラウザでDBに登録されている全ての情報を取得し表示する時の動作。 ブラウザ(情報取得ボタン押下) ↓ サーブレット:DB(情報取得) ↓ ブラウザ(結果出力)  DBからの情報取得の処理が多少時間がかかってしまうため、その間にブラウザの中止ボタンが押下されてしまう場合があります。  その場合、ブラウザ⇔HTTPサーバ(Tomcat)でのセッションは切れているのですが、サーブレットの処理は継続して行われています。  再度、情報取得ボタンが押下されると、前提条件でスレッドが1つしか作成しないようにしているため、前の処理が終了するまで待機しするという形になっています。  この場合、中止→取得→中止→取得と何度も繰り返される(IEの場合取得ボタンを連打でも可)と、さらに結果の出力が遅くなるということがおきてしまいます。  これを解決するために、Tomcatが新しいリクエストを受け取った場合、現在のスレッドを破棄するといった形にできればと考えています。  上記の考えで調査を行っているのですが、良い情報を見つけることが出来ません。    実際にTomcatが現在実行中のスレッドを破棄し、新しいリクエストを受付けて処理を実行するといったようなことはできるのでしょうか?  ご存知の方がいらっしゃったら、どうか助言をよろしくお願いいたします。