在C中的线程内定期调用函数

时间:2013-07-16 11:05:45

标签: c multithreading function timer

我正在用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;
}

2 个答案:

答案 0 :(得分:1)

一般来说这没关系。但是你应该考虑一些注意事项:

  1. 您必须同步对传输频道的访问才能获得一些非常奇怪,难以追踪和重现的效果
  2. 不要将刷新命令的超时精确设置为5秒,例如比5s低一半或几个百分点。否则你可能会受到抖动引起的影响。 (例如,如果摄像机的时基与PC的时基一样准确,如果您在5秒后发送请求,摄像机将在5秒+传输时间后收到“保持活动”消息。这将是超时。 / LI>
  3. 考虑引入一个门卫线程或对象来序列化对您的通信通道的访问。这将为您提供一些优化机会。例如,我可以想象,如果您刚刚发出命令,则不必发送保持活动状态。
  4. 不要用while(1)启动线程。将线程的引用交给一个值或一个事件对象,它允许您发出应该终止它的线程的信号。这使您有机会在关闭程序时正确清理所有内容。
  5. 如果您希望我进一步解释一些注意事项,请告诉我。

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

    这是什么意思?想象一下,该线程接受了互斥体,即将发送一些东西,并且正好在那个时候你的主线程终止线程。在这种情况下,您的互斥锁可能会保持锁定状态,其他所有人都无法获取它。 (例如,发送会话销毁命令)。

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

答案 1 :(得分:0)

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