Automatiza iniciar vários encadeamentos de tela paralelos?

1

Nossa escola HPC não tem um agendador. Portanto, não há nada como a fila de trabalhos. Portanto, não posso automatizar o envio de trabalhos paralelos por qsub ou sbatch .

O que eu tenho usado para "enviar" um trabalho é usando a tela: digite screen , depois pressione Enter , digite ./runMyJob.sh e pressione CTRL + a seguido por d para desanexar.

Agora, desejo automatizar / rotear o processo de iniciar várias sessões de tela paralelas, depois executar um trabalho em cada sessão e, finalmente, desanexar todas as sessões de tela.

Como você pode ver, durante as operações manuais, pressionei Enter e CTRL + a seguido por d . Como eu escrevo estas operações de pressionamento de teclas?

P.S .: qualquer sugestão que ajude a conseguir submissão de trabalhos paralelos em uma HPC sem agendador é muito bem-vinda!

    
por Sibbs Gambling 04.10.2014 / 18:15

2 respostas

2

Não pense nisso em termos de pressionar teclas, pense nisso em termos de realizar uma tarefa. Pressionando as teclas é uma maneira de fazer as coisas de forma interativa. A maneira de realizar as coisas automaticamente é roteirizá-las.

Para iniciar um trabalho na tela e desconectá-lo imediatamente, execute

screen -md ./runMyJob.sh

Se você quiser facilitar a localização de seus trabalhos, pode passar a opção -S para definir um nome de sessão.

Por exemplo, você pode escrever o seguinte script, que usa o nome do executável do trabalho como o nome da sessão:

#!/bin/sh
screen -md -S "${1##*/}" "$@"

Chame de algo como submit , coloque-o em um diretório em seu PATH ( Local de instalação binária de usuário único? e Como adicionar caminho de diretório inicial a ser descoberto pelo Unix qual comando? pode ajudar), torne-o executável ( chmod +x ~/bin/submit ). Para iniciar um trabalho, execute

submit ./runMyJob.sh

Para execução paralela, você pode querer investigar o paralelo GNU .

Observe que uma estrutura de envio de trabalho faz mais do que iniciar trabalhos. Ele também permite que eles sejam executados onde há tempo e memória da CPU disponíveis e para enviar logs para os remetentes. Você deve solicitar que seus administradores configurem uma estrutura de envio de trabalhos adequada.

    
por 06.10.2014 / 00:02
0

Digite , Ctrl - a e d gera códigos ASCII normais.

Portanto, uma possível solução poderia ser um programa que cria um canal não nomeado ( pipe() ), então fork() sa processo filho que primeiro vincula a extremidade de leitura do canal a sua entrada padrão e, em seguida, executa screen no processo filho ( execve() ou similar). Se esse programa for iniciado, você pode escrever as linhas de comando necessárias para iniciar um processo na extremidade de gravação do canal criado.

Como você coloca as tarefas nesse programa é outro tópico. Você poderia, por exemplo, escrever um pequeno programador (algo como uma fila de tarefas e algum código que inicia no máximo N processos em paralelo).

== EDIT ==

Para o Linux (ou talvez alguns UN * Xes, também), o programa pode se parecer com o seguinte:

#include <sys/types.h>
#include <sys/linux.h>
#include <unistd.h>

int main(void) {
    int fds[2] = {0};
    pid_t pid = 0;

    pipe(fds);               /* Creates an unnamed pipe */
    pid = fork();            /* Forks a new process */
    if (pid == 0) {
        static char const *argv[] = {"/usr/bin/screen", NULL};
                             /* Note: The array might need to be changed,
                              *       depending on your requirements
                              *       (eg. command-line arguments)
                              */
        dup2(fds[0], stdin); /* Binds the read end of the pipe to stdin */
        execve(argv[0], argv, NULL);
        /* If you reach this point, your execve() failed */
    }
    sleep(1);                /* Waits for the child process to execute
                              * screen */
    char const data[] = "./MyJob.sh\n\x00d";
                             /* Note: You must replace the '\x00' by the
                              *       ASCII code of C-a!
                              */
    write(fds[1], data, sizeof(data));
                             /* Writes the name of the job along with the
                              * control codes to the child process
                              */
    int retcode = 0;
    waitpid(pid, &retcode, 0);
                             /* Waits for the child process to terminate */
                             /* Note: WEXITSTATUS(retcode) gets the exit
                              *       status of the child process */
    return 0;
}

Este programa deve ilustrar a ideia, ele não tem o tratamento de erros necessário.

    
por 04.10.2014 / 18:31

Tags