1

Wi-Fi経由でビデオカメラに接続し、ユーザーがこれらの機能を実行したいときにズーム、録画の開始と停止を制御できるC言語でプログラムを書いています。

ビデオカメラに最初に接続した後、5 秒ごとにセッション更新コマンドを送信する必要があります。したがって、私の考えは、5秒ごとに更新コマンドを送信する最初の接続後に新しいスレッドを開始することでした。

while(1) {
    sendRefreshCommand(); 
    usleep(5000000); 
}

このアイデアは大丈夫​​ですか、それを達成する他の方法はありますか?


編集:これまでのところ、私がやりたいことを少し説明するための私のコードです。ユーザーは、何をしたいかを永続的に尋ねられます。これはテストのみを目的としています。後でズームと録画コマンドがプログラムによって自動的に実行されます。ユーザーにセッションを 5 秒ごとに更新するように求めるのと並行して。

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include "camctrl.h"

extern struct conf  g_Config;

void* sessionContinueThread(void *session_args){
    while(1){
        sessionContinue(g_Config.cam_ip);
        usleep(3000000);
    }
}

int main(){
int         sel;
pthread_t   session_thread;
void        *arg2;

readConfig("config2.json");

ConnectToCam(g_Config.cam_ip);

arg2 = (void *) g_Config.cam_ip;
pthread_create( &session_thread , NULL , sessionContinueThread , arg2 );
pthread_join(session_thread,NULL);

while(1){
    printf("\n[0] Zoom Tele\n");
    printf("[1] Zoom Wide\n");
    printf("[2] Start Recording\n");
    printf("[3] Stop Recording\n");
    printf("[4] Session Continue\n");
    printf("[5]Stop\n");
    printf("Selection: ");
    scanf("%d",&sel);

    switch( sel ){
        case 0: zoomTele(); break;
        case 1: zoomWide(); break;
        case 2: RecStart(); break;
        case 3: RecStop(); break;
        case 4: sessionContinue(g_Config.cam_ip); break;
        case 5: exit(0); break;
        default: break;
    }
}
return 0;
}
4

2 に答える 2

1

通常、これで問題ありません。ただし、次の点について考慮する必要があります。

  1. 非常に奇妙で追跡が難しく、影響を再現することがないように、伝送チャネルへのアクセスを同期する必要があります。
  2. リフレッシュ コマンドのタイムアウトを正確に 5 秒に設定しないでください。たとえば、5 秒よりも半分または数パーセント短くしてください。そうしないと、ジッターから生じる影響を受ける可能性があります。(たとえば、カムコーダーのタイムベースが PC のタイムベースとほぼ同じくらい正確である場合、5 秒後に要求を送信すると、カムコーダーは 5 秒 + 送信時間後に「キープ アライブ」メッセージを受け取ります。これがタイムアウトになります。
  3. ゲートキーパー スレッドまたはオブジェクトを導入して、通信チャネルへのアクセスをシリアル化することを検討してください。これにより、最適化の機会が得られます。たとえば、コマンドを発行したばかりの場合、キープアライブを送信する必要はないと想像できます。
  4. while(1) でスレッドを開始しないでください。値またはイベント オブジェクトへの参照をスレッドに渡して、スレッドを終了する必要があることをスレッドに通知できるようにします。これにより、プログラムをシャットダウンするときにすべてを適切にクリーンアップする機会が得られます。

考慮事項のいくつかをさらに説明したい場合は、お知らせください。

編集: #4 の詳細説明: 割り当てたすべてのリソースをクリーンアップするように注意する必要があります。もちろん、OS がプロセスをメモリからスローするときにスレッドなどをクリーンアップする可能性があることを信頼できますが、それは実際には良い方法ではありません。したがって、スレッドを作成してプログラムを実行した後、プログラムが終了するときにスレッドも破棄する必要があります。そうするために、もちろん、スレッドをすぐに終了させるいくつかの呼び出しを呼び出すことができます。その欠点は、未定義の状態でいくつかのもの (例: ミューテックス) を残す可能性があることです。

これは何を意味するのでしょうか?スレッドがミューテックスを取得し、何かを送信しようとしていて、まさにその時点でメインスレッドがスレッドを終了したと想像してください。この場合、mutex がロックされたままになり、他の誰もがそれを取得できなくなります。(たとえば、セッション破棄コマンドを送信するため)。

したがって、このようなことを回避する解決策は、外部から強制的に終了させるのではなく、スレッドに終了を要求することです。要求により、スレッドは割り当てまたは取得した可能性のあるものをクリーンアップして終了する機会が残されます。他のスレッドに終了を要求しているスレッドは、自分自身を終了する前に他のスレッドを待機する必要があります (一種の結合関数を使用)。

于 2013-07-16T11:20:49.313 に答える
0

あなたのアイデアは良さそうです。アラーム シグナルとシグナル ハンドラを使用して、同じことを実現できます。引数として 5 を渡すことにより、アラーム シグナルとアラーム シグナルの立ち上がりのシグナル ハンドラを初期化します。5 秒後、プロセスは sigalarm シグナルを受信し、sigalrm のシグナル ハンドラを呼び出します。シグナル ハンドラで refresh コマンドを送信し、再び sigalrm を 5 秒間発生させます。このループは継続的に機能します。ただし、メインプログラムの実行は、sigalrm を受信するたびに停止します。

于 2013-07-16T11:17:50.547 に答える