несколько буферов с использованием потоков

0

Мне нужна помощь по алгоритму с многопоточной программой, которую я пишу. Это в основном команда cp в unix, но с прочитанным потоком и потоком записи. Я использую семафоры для синхронизации потоков. У меня есть структуры для данных буфера и потока, определенные как

struct bufType {
    char buf[BUFFER_SIZE];
    int numBytes;
};

struct threadData {
    int fd;
    bufType buf;
};

и глобальный массив bufType. Код для моего основного

int main(int argc, const char * argv[])
{
    int in, out;
    pthread_t Producer, Consumer;
    threadData producerData, consumerData;

    if (argc != 3)
    {
        cout << "Error: incorrect number of params" << endl;
        exit(0);
    }
    if ((in = open(argv[1], O_RDONLY, 0666)) == -1)
    {
        cout << "Error: cannot open input file" << endl;
        exit(0);
    }
    if ((out = open(argv[2], O_WRONLY | O_CREAT, 0666)) == -1)
    {
        cout << "Cannot create output file" << endl;
        exit(0);
    }

    sem_init(&sem_empty, 0, NUM_BUFFERS);
    sem_init(&sem_full, 0, 0);

    pthread_create (&Producer, NULL, read_thread, (void *) &producerData);
    pthread_create (&Consumer, NULL, write_thread, (void *) &consumerData);

    pthread_join(Producer, NULL);
    pthread_join(Consumer, NULL);

    return 0;
}

и читать и писать темы:

void *read_thread(void *data)
{
    threadData *thread_data;
    thread_data = (threadData *) data;

    while((thread_data->buf.numBytes = slow_read(thread_data->fd, thread_data->buf.buf, BUFFER_SIZE)) != 0)
    {
        sem_post(&sem_full);
        sem_wait(&sem_empty);
    }

    pthread_exit(0);
}

void *write_thread(void *data)
{
    threadData *thread_data;
    thread_data = (threadData *) data;

    sem_wait(&sem_full);
    slow_write(thread_data->fd, thread_data->buf.buf, thread_data->buf.numBytes);
    sem_post(&sem_empty);

    pthread_exit(0);
}

Поэтому моя проблема заключается в том, что назначить переменным threadData в main и моей логике семафора в потоках чтения и записи. Я ценю любую помощь, которую вы можете дать

Теги:
multithreading
system-calls
thread-synchronization

2 ответа

0
Лучший ответ

Будучи парнем Windows, который не использует файловые дескрипторы, я могу ошибаться в работе и выходе, но я думаю, что это необходимо сделать в основном, чтобы настроить структуры threadData.

producerData.fd = in;
consumerData.fd = out;

Затем объявите объект ONE SINGLE типа bufType для обеих структур. Измените, например, определение threadData для

struct threadData {
    int fd;
    bufType* buf;
};

и в вашем Мастере вы пишете

bufType buffer;
producerData.buf = &buffer;
consumerData.buf = &buffer;

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

Затем вам нужно изменить свою сигнальную логику. Прямо сейчас ваша программа не может принимать входные данные, которые превышают BUFFER_SIZE, потому что ваш поток записи будет писать только один раз. Там должна быть петля. И тогда вам нужен какой-то механизм, который сигнализирует потоку записи, что больше не будет отправлено данных. Например, вы можете сделать это

void *read_thread(void *data)
{
    threadData *thread_data;
    thread_data = (threadData *) data;

    while((thread_data->buf->numBytes = slow_read(thread_data->fd, thread_data->buf->buf, BUFFER_SIZE)) > 0)
    {
        sem_post(&sem_full);
        sem_wait(&sem_empty);
    }
    sem_post(&sem_full); // Note that thread_data->buf->numBytes <= 0 now

    pthread_exit(0);
}

void *write_thread(void *data)
{
    threadData *thread_data;
    thread_data = (threadData *) data;


    sem_wait(&sem_full);
    while (thread_data->buf->numBytes > 0)
    {
        slow_write(thread_data->fd, thread_data->buf->buf, thread_data->buf->numBytes);
        sem_post(&sem_empty);
        sem_wait(&sem_full);
    }
    pthread_exit(0);
}

Надеюсь, ошибок больше нет, не тестировал решение. Но концепция должна быть тем, о чем вы просили.

  • 0
    Я думаю, что это выведет меня на правильный путь. Единственная проблема, я должен использовать несколько буферов, и я забыл включить это в вопрос. Таким образом, массив bufType
  • 0
    Я не понимаю, как это должно работать с несколькими буферами. Оба потока должны совместно использовать буфер, или они не могут общаться
Показать ещё 4 комментария
0

Вы можете использовать общий буферный пул, либо круглый массив, либо связанные списки. Вот ссылка на zip в примере Windows, который похож на то, что вы просите, используя связанные списки как часть системы обмена сообщениями между потоками для буферизации данных. Помимо создания мьютексов, семафоров и потока записи, функции малы и просты. mtcopy.zip.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню