c - 并行运行两个程序,每个程序都有无限循环

标签 c loops for-loop parallel-processing

我有一个语音识别程序,它是基于连续的语音识别(来源:CMU SPHINX) 它包含一个无限for循环,如下所示;

for (;;) {
wait for start of next utterance;
decode utterance until silence of at least 1 sec observed;
print utterance result;
}


// Partial code where i tried to do the both operation -----

recognize_from_microphone()
{
ad_rec_t *ad;
int16 adbuf[4096];
int32 k, ts, rem;
char const *hyp;
char const *uttid;
cont_ad_t *cont;
char word[256];
int counter_correct;
int Nummer1, Nummer2, Nummer3, Nummer4,id;
int token = 500;
struct sockaddr_in my_addr, cli_addr[2],cli_temp;
int sockfd;
socklen_t slen[2],slen_temp;
slen[0]=sizeof(cli_addr[0]);
slen[1]=sizeof(cli_addr[1]);
slen_temp = sizeof(cli_temp);
char buf[BUFLEN];
int clients = 0;
int client_port[2];

if ((ad = ad_open_dev(cmd_ln_str_r(config, "-adcdev"),
(int) cmd_ln_float32_r(config,
"-samprate"))) == NULL)
E_FATAL("Failed to open audio device\n");

/* Initialize continuous listening module */
if ((cont = cont_ad_init(ad, ad_read)) == NULL)
E_FATAL("Failed to initialize voice activity detection\n");
if (ad_start_rec(ad) < 0)
E_FATAL("Failed to start recording\n");
if (cont_ad_calib(cont) < 0)
E_FATAL("Failed to calibrate voice activity detection\n");

printf("\n\n");
system("setterm -bold on");



if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
{
    printf("test\n");
    err("socket");
    }else{
    printf("Server : Socket() successful\n");
}
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);

if (bind(sockfd, (struct sockaddr* ) &my_addr, sizeof(my_addr))==-1)
{
    err("bind");
    }else{
    printf("Server : bind() successful\n");
}

for (;;) {


    //receive
    printf("Receiving...\n");
    if (recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_temp, &slen_temp)==-1)  {
        err("recvfrom()");
    }
    if (clients==0) {
        cli_addr[0] = cli_temp;
        //get client 0 port
        client_port[0] = ntohs(cli_addr[0].sin_port);
        clients++;
        printf("Client 0 connected. Port: %d\n",client_port[0]);
        sendto(sockfd, "You are the first client.", 24, 0, (struct sockaddr*)&cli_temp, slen_temp);
        }else if (clients==1) {
        //new or existing
        if (client_port[0]==ntohs(cli_temp.sin_port)) {
            //send back to client 0 that nobody else connected yet
            sendto(sockfd, "You are the first client.", 24, 0, (struct sockaddr*)&cli_addr[0], slen[0]);
            printf("Only client\n");
        }else
        {
            //new connection
            cli_addr[1] = cli_temp;
            client_port[1] = ntohs(cli_addr[1].sin_port);
            clients++;
            printf("Second client\n");
            sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr[0], slen[0]);
        }
        }else{
        //there are 2 clients connected here. If we get an error from the sendto then we decrement clients
        if (client_port[0]==ntohs(cli_temp.sin_port)) {
            //client 0 talking send to client 1
            printf("Sedning message to client 1\n");
            if (sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr[1], slen[1])==-1)
            {
                clients--;
                err("sendto()");
            }
            }else {
            //client 1 talking send to client 0
            printf("Sending message to client 0\n");
            if (sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr[0], slen[1])==-1)
            {
                clients--;
                err("sendto()");
            }
        }

    }
    /* Indicate listening for next utterance */
    //printf("\nTrainguard Terminal is hearing you ....\n");
    fflush(stdout);
    fflush(stderr);

    /* Wait data for next utterance */
    while ((k = cont_ad_read(cont, adbuf, 4096)) == 0)
    sleep_msec(100);

    if (k < 0)
    E_FATAL("Failed to read audio\n");

    /*
    * Non-zero amount of data received; start recognition of new utterance.
    * NULL argument to uttproc_begin_utt => automatic generation of utterance-id.
    */
    if (ps_start_utt(ps, NULL) < 0)
    E_FATAL("Failed to start utterance\n");
    ps_process_raw(ps, adbuf, k, FALSE, FALSE);
    //printf(" message - regarding the process begins \n");
    fflush(stdout);

    /* Note timestamp for this first block of data */
    ts = cont->read_ts;

    /* Decode utterance until end (marked by a "long" silence, >1sec) */
    for (;;) {
        /* Read non-silence audio data, if any, from continuous listening module */
        if ((k = cont_ad_read(cont, adbuf, 4096)) < 0)
        E_FATAL("Failed to read audio\n");
        if (k == 0) {
            /*
            * No speech data available; check current timestamp with most recent
            * speech to see if more than 1 sec elapsed.  If so, end of utterance.
            */
            if ((cont->read_ts - ts) > DEFAULT_SAMPLES_PER_SEC / 4)
            break;
        }
        else {
            /* New speech data received; note current timestamp */
            ts = cont->read_ts;
        }

        /*
        * Decode whatever data was read above.
        */
        rem = ps_process_raw(ps, adbuf, k, FALSE, FALSE);

        /* If no work to be done, sleep a bit */
        if ((rem == 0) && (k == 0))
        sleep_msec(20);
    }

    /*
    * Utterance ended; flush any accumulated, unprocessed A/D data and stop
    * listening until current utterance completely decoded
    */
    ad_stop_rec(ad);
    while (ad_read(ad, adbuf, 4096) >= 0);
    cont_ad_reset(cont);

    //printf("Processing...\n");
    fflush(stdout);
    /* Finish decoding, obtain and print result */
    ps_end_utt(ps);
    hyp = ps_get_hyp(ps, NULL, &uttid);
    //printf("%s: %s\n", uttid, hyp);
    fflush(stdout);
    /* Exit if the word spoken was "THATS ALL".  Change string in strcmp() for another phrase. */
    if (hyp) {
        sscanf(hyp, "%s", word);
        if (strcmp(hyp, "LASCHE FAHRPLAN") == 0 &&(token==500) ) {
            counter_correct = counter_correct + 1;
            printf("LASCHE FAHRPLAN   \n");
            printf("score %d/%s \n",counter_correct,uttid);
        }

    }

    /* Resume A/D recording for next utterance */
    if (ad_start_rec(ad) < 0)
    E_FATAL("ad_start_rec failed\n");
}


cont_ad_close(cont);
close(sockfd);
}



// Code ends here

我有另一个服务器客户端程序,它也包含无限循环。它接受来自客户端 A 的数据并将其发送给客户端 B。 它还将特定信息从客户端 B 发送给客户端 A。

我想将两者结合起来,这样它就可以接受客户端A的数据并将其发送给客户端B,同时也将客户端B的特定信息发送给客户端A。除此之外,当告知特定命令时,来自客户端的消息A 将被修改并发送给客户端 B。

我将这两个程序组合在一起,因为它们具有共同的无限循环类型,但是尽管我在客户端 A 和客户端 B 之间正确通信,但我的语音识别不再提供输出。 :(

任何人都可以建议,如何并行运行这两个基于连续的程序?

最佳答案

循环的第一部分使用 recvfromsendto 函数。这些是阻塞 I/O 函数。也就是说,在收到或发送所请求的数据之前,它们不会返回。

通过将这两项事件放在同一个循环中,您可以确保每次传入网络读取只能执行一项语音事件,反之,每次语音 session 只能发生一项网络事务。

此问题有两种解决方案:

  1. 对每个事件使用不同的线程或进程。

  2. 使用非阻塞 I/O。

您可以通过将网络代码全部包装在一个大的 if 语句中来使网络代码成为非阻塞的,该语句仅在 select 系统调用表明读取不会阻塞时运行。我想,您可以通过调整 cont_ad_read 循环来使语音输入不被阻塞(但尚未检查)。

但是,如果此事件不相关(即一个事件不依赖于另一个事件),我认为多个线程将是更好的选择。

关于c - 并行运行两个程序,每个程序都有无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25870867/

相关文章:

php - 当 SUM 用于特定条件时,如何避免在 FOREACH block 中进行 MySQL 查询?

c - 尝试用 C 语言编写输出棋盘格的代码

java - 在 for 循环之前显示 toast 不起作用

c++ - 如何使用基于范围的 for 循环修改 map 中的值?

c - 如何使用 n - 1 个线程对 n 个元素的数组进行排序

c++ - 不使用 ATL 实现 COM IDispatch

c - 使用多维数组优化 C 以实现性能与内存优化

c - ANSI C 中 main 的参数是否有默认类型,或者 gcc 只是慷慨?

c - 使用循环在数组中生成唯一随机数

java - while 循环,为 java 中的下一个 while 循环存储值