ワーカスレッドAfxBeginThreadのスレッド起動を遅延させる方法

このQ&Aのポイント
  • マルチスレッド化しているアラームメールの起動間隔を伸ばすためにSleepを使用したが効果がなかった。
  • OCNのメールサーバーを使用する際に、セッションの数を制限されているため、間隔なしにアラームメールが送信されてしまう。
  • スレッドの起動間隔を遅延させるためにはAfxBeginThreadの後にSleepを挿入するが、現在の実装では効果がない。
回答を見る
  • ベストアンサー

ワーカスレッド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 );の間違い? } 念の為 スレッド起動をしなければいいのですが、単純にはいかなかった ため、応急処置としてスレッドの起動間隔を遅延させる方法を どうにかできないものでしょうか。あくまでも応急処置として、 お願いいたします。

noname#204416
noname#204416

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

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

AfxBeginThreadの 引数dwCreateにCREATE_SUSPENDEDを指定してスレッドを作成するようにしてみてはいかがでしょう その後 ResumeThreadメソッドでスレッド起動 WaitForSingleObjectなどを使ってスレッドが終了する毎に次スレッドのResumeThreadを呼んでみてはいかがでしょう ... for(i=0; i< ALARM_MAX;i++) { m_pThread[i] = AfxBeginThread( ThreadProcCL,(LPVOID)i,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED); } for( i=0; i<ALAM_MAX; i++) { m_pThread[i]->ResumeThread(); while( WaitForSingleObject( m_pThread[i]->m_hThread, 100 )!= WAIT_OBJECT_0) { Sleep( 5 * 1000 ); } }

noname#204416
質問者

補足

while( WaitForSingleObject( m_pThread[i]->m_hThread, 100 )!= WAIT_OBJECT_0) { このコードは、プログラムが転けるので。 while( WaitForSingleObject( m_pThread[i]->m_hThread, 100 )!= WAIT_OBJECT_0) { こちらで良いのかと思いましたが・・・。 他のサイトでもこちらの書き方が多いですし。 後述のコード内容の認識として、100msec間隔でシグナル状態になっているか判断して抜けると思いますが、自信がありません。orz。  今回のことは大変役に立ちました。 もう一度VC++を勉強していこうかなぁと思いました、ありがとうございました。

関連するQ&A

  • スレッドを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回表示されて終了してしまいます。 どこか間違えがあるのでしょうか。。

  • スレッド制御に関して

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

  • スレッドAで信号を送り、返答があったときにスレッドBを起動、スレッドAの信号のデータを初期化する方法

    VC6.0で開発しています。 今、次のような処理をどうすればよいか悩んでいます。ヒントになる回答を頂けたら幸いです。 データをやり取りする際、どのような処理を行うか命令するもの(以下、命令A)と、命令された通りのデータを送るもの(以下、送信B)、そして、AとBの通信部分を担うもの(以下、通信C)があります。 データのやりとりは、マルチスレッドで行っています。 データをやりとりするために、スレッドが通信C上で2つ起動しています。1つ目のスレッド(以下、スレッドA)は、送信Bが命令Aから送られる特定のデータ(以下、データA)を受け取れるかをどうかの信号を、命令Aに送るためのものです。2つ目のスレッド(以下、スレッドB)は、データAを通信Cが受け取り、送信Bに渡すときに起動するスレッドです。 スレッドAで、送信Bから命令Aへ、受信の準備ができたことを伝える信号が送られます。その後、命令AよりデータAが送られ、通信CでスレッドBが起動するのですが、データAを通信Cで受信したとき、スレッドAで送っている信号を初期化しなければいけません。 データAを受信したときにはスレッドBが起動しますので、スレッドAとスレッドBの間での処理ということになります。 スレッド処理について、まだまだ不勉強なのですが、よいアイディアがあれば教えてください。 よろしくお願いします。

  • マルチスレッド

    VC++でスレッドを立ち上げるとき、AfxBeginThread()を使いますよね。 ↓こんな感じ AfxBeginThread( ::ThreadFunc, &m_stThreadInfo ); そこでもし、スレッドの起動に失敗したとしたら、どうなるのでしょうか。 エラーチェックはどのようにして行えばいいのでしょうか。

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

    現在、下記のようなプログラムを作成しています。 内容は、メッセージキューを受信するスレッドを生成するというイメージです。 処理内容は下記のようになります。  (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; } ----------------------------------------------------------------

  • ThreadとRunnableのlogへの表示差異

    マルチスレッドでsleep()の時間を指定して動かすのを前提で、 Threadを継承した時は、時間通りに(リアルタイムで) eclipseのコンソールへ表示されるのですが、 Runnableをインプリメントしての動作では、 eclipseのコンソールに一瞬で表示されるのは何故でしょうか? public class MultiThread3 implements Runnable{ int time; MultiThread3(int time) { this.time = time; } public void run() { for(int i=0; i<5; i++) System.out.println("No."+i+":"+Thread.currentThread().getName()); try{ Thread.sleep(time); }catch (InterruptedException e) {} } } class MultiThreadTest3{ public static void main(String[] args) { MultiThread3 a = new MultiThread3(500); MultiThread3 b = new MultiThread3(700); MultiThread3 c = new MultiThread3(1100); Thread ta = new Thread(a); Thread tb = new Thread(b); Thread tc = new Thread(c); ta.setName("A"); tb.setName("\tB"); tc.setName("\t\tC"); ta.start(); tb.start(); tc.start(); } }

    • ベストアンサー
    • Java
  • (マルチスレッド)_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); } }

  • VC++ スレッドからDoModalへ

    いまさらですがVC++6.0でつまづいています MFCです AdlgクラスのダイアログのOnButtonA() からXXXスレッドを起動し そのXXXスレッドではcountを+1しつづけます。 そして別のダイアログ DDD10をDoModalで起動しそのDDD10 内のTextBoxの値にcount値を反映させて表示しようとしました 下記ソース内のAfxMessageBox(tmp);ではcount値は 更新されますが DDD10ダイアログ内のテキストボックス の値が変更されません m_gui_xfr_totalはDDD10のテキストボックスにつけた メンバー名です どなたかアドバイスをお願いします void ADlg::OnButtonA() { DDD10 dlg10 ; CWinThread *pThread = AfxBeginThread(XXX_thread_entry,(LPVOID *)this); dlg10.DoModal() ; } void XXX_Thread(){ CString tmp; unsigned int count=0; DDD10 dlg10; while(1){ count++; tmp.Format("%d",count); dlg10.m_gui_xfr_total.Format(tmp); AfxMessageBox(tmp); Sleep(1000); } }

  • javaのスレッドの割込みについて

    javaのスレッド割込みに関する初心者の質問です。 割込みの発生元でCNTに値を設定し、割込みの受信元でCNTの値を読込み、表示しています。 下記のコードを参照ください。 Q1)CNTの値の設定と読込みで競合が発生する様なことはありませんか? 又は、処理が停滞するとか 以上、お手数をお掛けしますが、宜しくお願いします。 //割り込を発生するスレッド class threadA extends base{ private Thread target; public threadA(Thread targetA){ target = targetA; } public void run(){ for(int i = 0; i < 8;i++){ try{ System.out.print("."); Thread.sleep(1); CNT=i; target.interrupt(); }catch(InterruptedException e){ System.out.println("今割り込まれました: thread"); } } } } //スレッドからの割り込みを受信するルーチン class Sample108{ public static void main(String args[]){ //for(int i=0; i<2; i++){ classA obj = new classA(); obj.threadStart();//割り込みを受けるルーチン、この中で、割り込みを発生するルーチンを起動している //} } } //割り込みを受けるルーチン class classA extends base{ void threadStart(){ System.out.println("Start: main****"); threadA obj = new threadA(Thread.currentThread()); obj.start(); //Thread起動 //mainのルーチン for(int j = 0;j < 20; j++){ try{ Thread.sleep(1); System.out.print("*"); }catch(InterruptedException e){ System.out.println("今割り込まれました: classA CNT="+CNT); } } } } 以上

    • ベストアンサー
    • Java
  • Postfixのスレッドごとに別々のIPアドレスを設定するには

    Postfixを使用してリレーメールサーバの開発を行っております。 そこで質問なのですが、Postfixのプロセスを1つ起動し、メール送信時に そのプロセス上のスレッドごとに違うIPを設定することは出来ますでしょうか? 以下のようなイメージになります。 ※IPは仮称です。 Postfix ├─Thread1(122.216.137.92) ├─Thread2(122.216.137.93) ├─Thread3(122.216.137.94) ├─Thread4(122.216.137.95) ├─Thread5(122.216.137.96) ├─Thread6(122.216.137.97) ├─Thread7(122.216.137.98) ├─Thread8(122.216.137.99) また、上記以外にも1つのPostfixプロセスでIPアドレスを変更しながらメールを 送信する手法はありますでしょうか? サーバは以下の構成です。 OS: Ledhat ES4 MTA: Postfix2.5 NICは2ポート空いております。 以上、宜しくお願い致します。

専門家に質問してみよう