отправлять одни и те же данные в несколько потоков по каналам? - PullRequest
0 голосов
/ 20 сентября 2011

У меня есть менеджер ресурсов, который обрабатывает несколько TCP-соединений. Эти связи являются нитями. Как мне управлять отправкой данных из Ressource Manager во все эти потоки? Или даже лучше: как я могу выяснить, в какой поток я должен отправить эту команду?

Например: у меня есть 2 потока, один с pid 3333, один с pid 4444. Пользователь отправляет задание на программирование платы (это менеджер ресурсов, который управляет FPGA-платами). Менеджер ресурсов выбирает доску из списка, где также сохраняется этот pid. Затем команда-программа должна быть отправлена ​​потоку с этим pid или, как я думал в первую очередь, всем потокам, и потоки решают, продолжать они или нет. Протокол выглядит так: <pid>#<board-id>#<file>

Я открываю 2 канала (для записи в потоки и чтения из потоков) в main.c и передаю их в качестве аргумента прослушивающему потоку (forthread -struct).

main.c
// open Pipes to SSL
    int rmsslpipe[2];
    int sslrmpipe[2];
    if (pipe(rmsslpipe) == -1) {
        writelog(LOGERROR, "main: could not create RM-SSL reading pipe");
        exit(1);
    }
    if (pipe(sslrmpipe) == -1) {
        writelog(LOGERROR, "main: could not create RM-SSL reading pipe");
        exit(1);
    }
    int rmtosslserver = rmsslpipe[1];
    int sslservertorm = sslrmpipe[0];

    // start SSL-Server as a pthread
    pthread_t thread;
    forthread* ft = malloc(sizeof(forthread));
    ft->rmtosslserver = rmsslpipe[0];
    ft->sslservertorm = sslrmpipe[1];
    pthread_mutex_t ftmutex;
    pthread_mutex_init(&ftmutex, NULL);
    ft->mutex = ftmutex;

    pthread_create(&thread, NULL, startProgramserver, (void*) ft);

Этот поток теперь прослушивает новые подключения, и, если есть новое подключение, он создает новый поток с forthread -структурой в качестве аргумента. В этой теме происходит действие:)

void* startProgramserver(void* ft) {

int sock, s;

forthread* f = (forthread*) ft;

// open TCP-Socket
sock = tcp_listen();

while(1){
    if((s=accept(sock,0,0))<0) {
        printf("Problem accepting");
        // try again
        sleep(60);
        continue;
    }

    writelog(LOGNOTE, "New SSL-Connection accepted");
    f->socket = s;
    pthread_t thread;
    pthread_create(&thread, NULL, serveClient, (void*) f);
}
exit(0);
}

Этот поток теперь инициализирует соединение, получает некоторую информацию от клиента и затем ждет, пока менеджер ресурсов получит новые команды.

n=read(f->rmtosslserver, bufw, BUFSIZZ);

Но это терпит неудачу, если существует более одного потока. Так как я могу справиться с этим?

Ответы [ 2 ]

1 голос
/ 20 сентября 2011

Если у вас один поток на каждую доску, в команде не нужно указывать «pid» - вам просто нужен способ найти правильный поток (или очередь, или что-то еще) для указанной платы.

Вы можете сохранить список ваших прямых структур и включить идентификатор структуры в структуру. Также включите способ передачи команд; это может быть канал, но вы можете использовать вместо него какую-то очередь или список. Таким образом, вы используете один канал (или другой механизм) для каждого потока вместо одного общего, и можете найти правильный канал для каждой платы, выполнив поиск в списке из четырех строк для одного с правильным идентификатором платы. Обязательно защитите все части структуры, которые могут быть изменены, пока поток работает с мьютексом.

Проблема с использованием одного канала, как вы предложили, состоит в том, что только один поток получит каждую команду - если она неправильная, слишком плохая; команда пропала.

0 голосов
/ 15 октября 2011

Ответ - да.Я бы использовал их список. Как бы то ни было, я могу открыть канал больше 1, когда скорость ПК очень низкая.2 соединения для 2 соединений.

...