1

我正在用 C 语言编写一个程序,它通过 wifi 连接到摄像机,并且可以在用户想要执行这些功能时控制缩放、开始和停止录制。

初次连接到摄像机后,我必须每 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. 考虑引入一个看门人线程或对象来序列化对您的通信通道的访问。这会给你一些优化的机会。例如,我可以想象,如果您只是发出命令,则不必发送 keep-alive。
  4. 不要使用 while(1) 启动线程。给线程一个对值或事件对象的引用,允许您向线程发出信号,它应该被终止。这使您有机会在关闭程序时正确清理所有内容。

如果您希望我进一步解释一些注意事项,请告诉我。

编辑:对 #4 的进一步解释:您应该注意清理分配的所有资源。当然,您可以依赖操作系统,因为它可能会在将您的进程从内存中抛出时清理线程和东西,但这并不是一个真正的好方法。因此,在创建线程并运行程序之后,您还应该在程序退出时销毁线程。为此,您当然可以调用一些立即终止线程的调用。不利的一面是,您可能碰巧将某些东西(例如互斥锁)置于未定义状态。

这是什么意思?想象一下线程拿走了互斥锁,正要发送一些东西,而正是在那个时间点,你的主线程终止了线程。在这种情况下,您的互斥锁可能会保持锁定状态,而其他所有人都无法获得它。(例如发送会话销毁命令)。

因此避免此类事情的解决方案是请求线程终止,而不是从外部强制终止。该请求使线程有机会清理他可能分配或获取的东西,然后退出。请求另一个线程终止的线程应该在退出之前等待另一个线程(使用一种连接函数)。

于 2013-07-16T11:20:49.313 回答
0

你的想法看起来不错。您可以通过使用警报信号和信号处理程序来实现相同的目的。通过传递 5 作为参数初始化警报信号和上升警报信号的信号处理程序。5 秒后,您的进程收到一个 sigalarm 信号并调用 sigalrm 的信号处理程序。在信号处理程序中发送刷新命令并再次提高 sigalrm 5 秒。这个循环连续工作。但事情是你的主程序执行在每次收到 sigalrm 时都会停止

于 2013-07-16T11:17:50.547 回答