• ベストアンサー

スレッド制御に関して

C言語の初心者です。 現在、スレッドの勉強をしております。 最近、pthreadをなんとなく理解しつつありますが、 下記の2点に関して試行錯誤しております。 (1)スレッドを周期的に起動したい (2)時間によって起動したい (1)は、例えば30秒毎にスレッドを起動させたい等といった、周期スレッドの生成方法です。今考えているのは、スレッドを生成後、スレッド生成元で30秒間sleepして、2回目のスレッドを起動…。といったイメージを考えております。 (2)に関しても同様で、例えば12時00分00秒にスレッドを生成したいというパターンで、スレッド生成元にて、時間を取得して、その時間が12時00分00秒であればスレッド生成を行うといったイメージを考えております。 上記2案とも初心者なりに考えた案なのですが、他によい案はありませんでしょうか? ご教授頂けますようよろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • f_attck
  • ベストアンサー率33% (40/118)
回答No.1

メイン側を30秒間sleepすると、その間メイン側では処理できなく なりますが、OKでしょうか 他だと、タイマースレッドを作っておいてメイン起動時に起こして おいて、イベント登録されると指定時間もしくは指定時間経過後に 登録元スレッドに対してイベントを発行するように作っておけば メイン側を止めずに、色んなユースケースに耐えられるように なると思います。

その他の回答 (1)

  • Lbfuvab
  • ベストアンサー率36% (7/19)
回答No.2

1はメッセージループを自分で処理しているのなら、 SetTimerでWM_TIMERを使う手もありです。(sleepは出来れば避けるべき もしくはf_attckさんのようにスレッドにウィンドウハンドルを渡して 独自メッセージを送ればいいです。 2は別スレッドで時間を計っておき(方法は問いません)時間が来れば送る と言った風にしておけばどうでしょう?

関連するQ&A

  • C++におけるスレッド制御に関して

    C++初心者です。 スレッド制御の勉強をしておりますが、 なかなかうまくいきません。 下記のソースのようにスレッド生成をしておりますが、 スレッド用メソッドには、*を付けて使用するしか方法はないのでしょうか? pthread_createに渡す第3パラメータをメソッド名のみにして、呼ばれ元のメソッドの戻り値をvoid* ではなく、void のみで実施したいと思っておりますが、方法がわかりません。 大変申し訳ございませんが、ご教授よろしくお願いいたします。 ############################################################## # pthread_test.cc ############################################################## #include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <unistd.h> /* * スレッドパラメータ格納用 */ typedef struct {  char printVal;  int interval; } ThreadParamT; // スレッドイニシャル関数 void *ThreadTest(void *arg) {  ThreadParamT *thread_test_param =(ThreadParamT*)arg;  while(1) {   fprintf(stderr,"%c", thread_test_param->printVal);   sleep(thread_test_param->interval);  }  return NULL; } int main(int argc,char *argv[]) {  int status;  // スレッドのパラメータ  pthread_t thread_test;  ThreadParamT thread_test_param;  thread_test_param.printVal = 'a';  thread_test_param.interval = 1;  // スレッドを生成  status=pthread_create(&thread_test, NULL, ThreadTest, &thread_test_param);  if(status!=0){   fprintf(stderr,"ERR! OUT!\n");   exit(1);  }  // 10s間待つ  sleep(10);  fprintf(stderr, "\n");  return 0; } ##############################################################

  • スレッドとメッセージキューに関して

    現在、下記のようなプログラムを作成しています。 内容は、メッセージキューを受信するスレッドを生成するというイメージです。 処理内容は下記のようになります。  (1)メッセージキューの生成  (2)スレッド生成(メッセージキュー受信側)  (3)スレッド停止  (4)メッセージキューの削除 しかし、(3)のスレッド停止を実施しても、(4)のメッセージキューの削除以降にて、msgrcvのエラーが出力されてしまいます。 スレッド停止を行ったことから、TestThreadは動作しなくなり、(4)のメッセージキューの削除にて、エラーともならずに終了することを望んでりますが、上手くいきません。 下記に作成しているプログラムを記載いたします。 正常終了をするには何がいけないのでしょうか? ご教授宜しくお願い致します。 [test.cc] ---------------------------------------------------------------- #include <time.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <ctype.h> #include <stdlib.h> #include <pthread.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/msg.h> // メソッドポインタ定義 typedef void (*testT); // スレッドID pthread_t threadId; // メッセージキュー識別子 int msqId; // 送受信するメッセージ struct msgbuf{ long int type; char data[BUFSIZ]; }; // テストスレッド void TestThread() { // メッセージ struct msgbuf message; while( 1 ) { printf("### TEST ###\n"); printf("msq start\n"); // 受信 if( msgrcv( msqId, &message, BUFSIZ, 0, 0 ) == -1) { printf("ERR! msgrcv errno[%d]\n", errno); continue; } printf("msq ed\n"); sleep(1); } return; } // メイン int main(int argc, char *argv[]) { // メッセージキュー識別子退避変数 int testMsqid; // スレッド操作リターン値 int status; // スレッドa用のパラメータ pthread_t thread_test; printf("### TEST START ###\n"); // メッセージキューの作成 if( (testMsqid = msgget((key_t)1111, 0666 | IPC_CREAT)) == -1 ) { printf("ERR! CREATE bkMsqId[%d]\n", testMsqid); return 1; } // メッセージキュー識別子を共通変数に設定 msqId = testMsqid; printf("msgget OK\n"); sleep(5); // スレッドを生成 status = pthread_create(&thread_test, NULL, (void*(*)(void*))TestThread, (void*)NULL); if(status!=0) { printf("pthread_create ng\n"); return 1; } printf("pthread_create OK\n"); sleep(5); // スレッド停止 status = pthread_cancel(thread_test); // スレッド停止結果 if ( status != 0 ) { printf("pthread_cancel ng\n"); return 1; } printf("pthread_cancel OK\n"); sleep(5); // メッセージキューの削除 if ( msgctl( msqId, IPC_RMID, NULL) == -1 ) { printf("msqId[%d] errno[%d]\n", msqId, errno); return 1; } printf("msgctl OK\n"); sleep(5); printf("### TEST E N D ###\n"); return 0; } ----------------------------------------------------------------

  • スレッドを効率的に使うとは?

    C言語&C++で、pthreadを利用して、ファイルのコンバートをいかに早くできるかに挑戦します。 たとえば、CPUが2つある場合。 スレッドが1つだと、CPUの50%の性能しか出ない。だから、二つ目のスレッドを使うという風に理解しています。スレッドを二つ使うことで、100%CPUの力を引き出せる。 しかし、スレッドはCPUの数以上に、生成できるという風にも理解しています。もちろん上限はある。 ただし、その場合は2つのCPUをある時間単位でくぎって、スレッドにふりわけて使い回しをする。 ということは、フルにCPUを最速で使いたい場合は、CPUの数だけスレッドを生成して利用するという理解でいいでしょうか? また、大きなファイルの場合、ファイルにメモリに読み込んで二つにわけて、2つのスレッドを同時に走らせてはやく終わらせるということも可能なのでしょうか?おそらく、RAWのデータならできるけど、何かフォーマットがあるものは難しそうですね。

  • ワーカスレッドAfxBeginThreadのスレッド起動を遅延させたい

    アラーム情報などをBASP21を用いてE-Mail送信するプログラムを マルチスレッドにしていました。 自己メールサーバーを立てていた場合は、1秒間に何件でもセッション 張ってもよかったのですが、訳あってOCNのメールサーバーを使うように したところ、1秒間に複数のセッションを張ると迷惑メール送信 と認識されるため、接続が拒否されていまいます。 そこで、マルチスレッド化しているアラームメールの起動間隔を伸ばす ためにAfxBeginThreadの後に Sleep( 5* 1000 ); を入れて1秒間に複数送信しないようにしたつもりなんです が、何故かSleepが効かな状況です。 エラー内容としては、次のように表示されます。 Too Many Session 421 細かく見ていくと、状況によって次のエラーでした。 http://homepage1.nifty.com/yito/anhttpd/winsock_error.html 10060 WSAETIMEDOUT 10061 WSAECONNREFUSED Connection refused ログを見てもスリープが効いておらず、間隔なしにアラームメールが 1秒間に10件近く送信されてしまいます。 一応渡されたスレッドの最後に AfxEndThreadを書いてみたり書かないようにしてみたんですが、 状況は変わらずです。 #include "stdafx.h" #include "windows.h" for( i=0;i<ALARM_MAX;i++ ){ m_pThreadCL[i] = AfxBeginThread(ThreadProcCL, (LPVOID)i,THREAD_PRIORITY_NORMAL) Sleep( 5 * 1000); //::Sleep( 5 * 1000 );の間違い? } 念の為 スレッド起動をしなければいいのですが、単純にはいかなかった ため、応急処置としてスレッドの起動間隔を遅延させる方法を どうにかできないものでしょうか。あくまでも応急処置として、 お願いいたします。

  • スレッドを2つ作って1秒ごとに2つのスレッドが数値を表示するプログラム

    スレッドを2つ作って1秒ごとに2つのスレッドが数値を表示するプログラムを作りたいのですがうまくいきません。 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<sys/socket.h> #include<arpa/inet.h> #include<unistd.h> #include<pthread.h> void *threadMain(void *threadArgs); int main(void) { int i = 0; pthread_t threadID; for(i = 0;i < 2;i++){ pthread_create(&threadID,NULL,threadMain,(void *)NULL); } } void *threadMain(void *threadArgs) { int i = 0; while(1){ printf("%d\n",++i); sleep(1); } } 上記プログラムを実行すると1が2回表示されて終了してしまいます。 どこか間違えがあるのでしょうか。。

  • gprofとスレッドについて

    こんにちは。 gprofの使用方法について伺いたいことがあります のでよろしくお願いします。 $gcc -pg -pthread ファイル名 $./a.out $gprof a.out gmon.out | less 上記のように実施したところ、 スレッドから呼び出される関数の時間が0.00秒となっており、測定されていないようです。 (関数内に遅延処理をいれても変わらずです) スレッドを使用するプログラムをgprofにかける際に、 注意すべき点などを教えていただけないでしょうか。

  • Thread とか Sleep とかについて質問です。   Javaで

    Thread とか Sleep とかについて質問です。   Javaでトランプゲームを作ってます。例えば、コンピュータの番で5枚のトランプをめくる間隔を1枚0.5秒くらい間隔でやらせる為には、Thread.sleep(500); を使えばいいんでしょうか? 普通にやると当然一瞬でめくってしまう為、時間かせぎをしたいのです。VB系をやってた時は、コードの中にSleep(500)を好きな場所に入れれば、簡単に出来てたのですが。Javaでは上手くいかなくて・・・。よろしくお願いします。 (オセロで1枚1枚ひっくり返す時とかもめくる間隔を空けたいです)

    • ベストアンサー
    • Java
  • Threading.Thread.Sleep()の前後の処理

    初めて質問します。(VB2008始めたばかりの初心者です) 昔のBASICでwaitやdelay、sleepなどといったプログラムの実行を一時止めることの出来るコマンドがあったと思いますが、 VB2008上で同じようなことさせてラベルの色を一定時間で変化させたいと思い、色々調べて Threading.Thread.Sleep()  というものを見つけました。実際使ってみるとThreading.Thread.Sleep()の前に書いた処理がうまく動作しません。 (下記のような簡単なコードですが) Private Sub Buttonstart_Click(ByVal sender As System.Object,_ ByVal e As System.EventArgs) Handles Buttonstart.Click    Label1.BackColor = Color.White     Threading.Thread.Sleep(2000)     Label1.BackColor = Color.Blue End Sub スタートボタンを押せばlabel1が白色になり2秒後に青にしたいのですが白色にならずに2秒後にいきなり青になってしまいます。 とても初歩的な間違いをしていると思うのですが解決できません。恥ずかしいと思いながらも質問させていただきます。アドバイスをお願いします。

  • クラス内でのpthread_createに関して

    C言語初心者です。 下記のようなソースにて、クラス内でのスレッドを行うことが目的です。 しかし、下記のpthread_createにてコンパイルエラーとなります。 キャストエラーのようなのですが、キャスト方法がわかりません。 初歩的な質問で、大変申し訳御座いませんが、ご教授頂けませんでしょうか? ################################################################ #include <stdio.h> #include <pthread.h> // Testクラス class Test{ private: // スレッド処理 void testThread() { printf("### THREAD START ###\n"); return; } public: // スレッド開始 void threadStart() { // スレッド生成戻り値 int status; // スレッド pthread_t thread; // スレッド生成 status = pthread_create( &thread, NULL, (void*(*)(void*))testThread, NULL ); // スレッド生成結果 if ( status != 0 ) { printf("ERR!! pthread_create NG\n"); } return; } }; // メイン実行 int main(int argc, char *argv[]) { // Testクラスオブジェクト Test test; printf("### TEST START ###\n"); test.threadStart(); printf("### TEST E N D ###\n"); return 0; } ################################################################ 宜しくお願い致します。 以上です。

  • [MFC]AfxBeginTreadでのスレッド強制終了の方法について

    WinInetで多数のクライアントとHTTP通信を行うプログラムを作成しています。 やりたい事は閉じたネットワークの中で 生きているホストを調べるということです。 HTTP_GETの可否で判断させるつもりですがpingでも構いません。 (DHCPサーバーのリース情報などは参照できない状態環境) 逐次処理で一台ずつタイムアウトは待ってられないので ホストの台数分だけスレッドを作成します(クラスCなら256台分)。 <!-- コード --> UINT MyThreadProc(LPVOID pParam) {  CMyHost* hostData = (CMyHost*)pParam;  hostData->Get();  return 0; } void CMyDlg::OnStart() {  CMyHost hostData[hostNum];  CWinThread* pThread[HostNum];  // 台数分スレッド起動  for (int i=0;i<(int)HostNum;i++) {   hostData[i].ipAddr = NetworkAddress + (DWORD)i;   pThread[i] = ::AfxBeginThread(MyThreadProc, &hostData[i]);  }  // 何秒か待つ  HANDLE timer = CreateWaitableTimer(NULL, FALSE, NULL);  WaitForSingleObject(timer, 10000);  // returnしてないスレッドがあっても全スレッド強制終了  /* 強制終了の仕方が分からない */ <!-- コードここまで --> 強制終了させるためには各スレッドにメッセージを投げて スレッド側でそれを判定するなどでしょうか? でも通信の終わってないスレッドは通信処理の最中なのだから どうやってメッセージを受け取ればいいのか想像つかないです。 (そもそもCInternerSessionでタイムアウトの使い方がよく分からない…、 もっとスマートな方法があれば教えていただきたいです。)

専門家に質問してみよう