【问题标题】:C - Terminating a process with signal()C - 使用 signal() 终止进程
【发布时间】:2013-06-07 00:07:40
【问题描述】:

我有一个服务器和一个客户端。客户端可以选择终止服务器。

我正在使用:

void killServer()
{
    int server_p_id;
FILE *file;

file = fopen(SERVER_INFO, "r");
if(file == NULL)
{
    fprintf(stderr, "\nErro ao abrir %s", SERVER_INFO);
    exit(EXIT_FAILURE);
}

fscanf(file, "%d", &server_p_id);
fclose(file);

kill -9 -server_p_id;
unlink(SERVER_FIFO);
}

/* some code */

if (!strcasecmp("fim",buffer)) 
            {
                signal(SIGUSR1, killServer);
                break;
            }

问题是进程没有被终止。这是正确的做法吗?

编辑:当前代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include "dict.h"

#define MAX 256

void killServer()
{
    int server_p_id;
    FILE *file;

    file = fopen(SERVER_INFO, "r");
    if(file == NULL)
    {
        fprintf(stderr, "\nErro ao abrir %s", SERVER_INFO);
        exit(EXIT_FAILURE);
    }

    fscanf(file, "%d", &server_p_id);
    fclose(file);

    kill(server_p_id, SIGKILL);
    unlink(SERVER_FIFO);
}


int main()
{
    int s_fifo_fd;   /* identificador do FIFO do servidor */
    int c_fifo_fd;   /* identificador do FIFO deste cliente */
    pergunta_t perg; /* mensagem do "tipo" pergunta */
    resposta_t resp; /* mensagem do "tipo" resposta */
    char buffer[80]; /* para a leitura da palavra a traduzir */
    char c_fifo_fname[25]; /* nome do FIFO deste cliente */
    long fflags;
    int read_res;
    CLEAR;

    //Abrir fifo do servidor
    s_fifo_fd = open(SERVER_FIFO, O_WRONLY); /* bloqueante */
    if (s_fifo_fd == -1)
        {
            fprintf(stderr, "\nO servidor não está a correr\n");
            exit(EXIT_FAILURE);
        }

    //Cria fifo para receber resposta do servidor
    perg.pid_cliente = getpid();
    sprintf(c_fifo_fname, CLIENT_FIFO, perg.pid_cliente);
    if (mkfifo(c_fifo_fname, 0777) == -1)
        {
            fprintf(stderr, "\nErro no FIFO para a resposta (1)");
            close(s_fifo_fd);
            exit(EXIT_FAILURE);
        }

    //Abre o fifo para receber a resposta do servidor
    c_fifo_fd = open(c_fifo_fname, O_RDONLY | O_NONBLOCK);
    if (c_fifo_fd == -1)
        {
            fprintf(stderr, "\nErro no FIFO para a resposta (2)\n");
            close(s_fifo_fd);
            unlink(c_fifo_fname);
            exit(EXIT_FAILURE);
        }

    fflags = fcntl(c_fifo_fd, F_GETFL);
    fflags ^= O_NONBLOCK; /* inverte a semântica de bloqueio */
    fcntl(c_fifo_fd, F_SETFL, fflags); /* bloqueante = on */

    perg.palavra[TAM_MAX-1] = '\0';

    printf("\tIntroduza os comandos pretendidos\n\n");

    /* Ciclo Principal */

    while (1)   /* caso escreva "fim" o programa termina */
        {

            /* ---- a) OBTEM PERGUNTA ---- */
            printf("[ADMIN] ");
            scanf("%s",buffer);

            if (!strcasecmp("fim",buffer)) 
            {
                signal(SIGUSR1, killServer);
                break;
            }

            strncpy(perg.palavra,buffer,TAM_MAX-1); //copia a palavra lida do "buffer" para a "perg.palavra"

            /* ---- b) ENVIA A PERGUNTA ---- */
            write(s_fifo_fd, & perg, sizeof(perg));

            /* ---- c) OBTEM A RESPOSTA ---- */
            read_res = read(c_fifo_fd, & resp, sizeof(resp));
            if (read_res == sizeof(resp))
                printf("[SERVER] %s\n", resp.palavra);
            else
                printf("Sem resposta ou resposta incompreensivel[%d]\n",read_res);
        }

    close(c_fifo_fd);
    close(s_fifo_fd);
    unlink(c_fifo_fname);

    printf("Programa Terminou com Exito!");
    return 1;
}

【问题讨论】:

  • 将 shell 代码内联到 C 中的绝妙方法!您必须忽略多少警告才能发现问题?
  • 你尝试编译这个吗?
  • @OliCharlesworth: http://stackoverflow.com 也编译...
  • @xRed:那行看起来是否像有效/有意义的 C 语言?
  • @xRed:让我们用-Wall -pedantic -ansi -Wstrict-prototypes 再试一次,只是为了好玩。然后从那时起总是使用它。请在此处提问之前适当地缩进您的代码。你是一个人问,我们是 数百 阅读它。另外,如果可能,请提供完整的代码。

标签: c linux process named-pipes


【解决方案1】:

kill 是一个函数指针。标准 C 不允许对函数指针进行指针运算,尽管许多编译器将其作为(相当无意义的)扩展提供。

简而言之,您的代码不是有效的 C。

但是,完全有效的 C 代码 kill(server_p_id, SIGKILL); 可能会满足您的要求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多