2012-05-05 4 views
0

Я пытаюсь создать библиотеку, которая будет писать в один файл, и будет работать в многопоточной среде. Требования:Многопоточный писатель: проблемы параллелизма с использованием cpp

  1. Проблемы с параллелизмом не будут возникать при записи в файл.
  2. Порядок, в котором обрабатываются потоки, не имеет значения.
  3. Библиотека должна быть неблокирующей, то есть функции записи и флеша возвращаются до того, как будет записан указанный буфер.

Вот что я до сих пор:

int write2device(char *buffer, int length) { 
    Task * task = new Task(id++,buffer,length); 
    pthread_t * thread = new pthread_t; 
    Argument * arg = new Argument; //A sturct with pthread_t and task fields 
    arg->task = task; 
    arg->thread = thread; 
    pthread_create(thread,NULL,deamonWrite,arg); 
    return 0; 
} 

void wait(Argument * arg) { 
    //manager is a singleton class that handles the threads database and related 
    //issues 
    manager->pushDeamon(arg->thread); 
    manager->lock(arg->task->getId()); //mutex - only one thread can write 
} 

void * deamonWrite(void * arg) { 
    Argument * temp = (Argument *) arg; 
    wait(temp); 
    //critical section 
    //will add signal() later 
    return NULL; 
} 

Идея заключается в том, что для каждого потока вызова write2device я открываю поток, который проходит deamonWrite(). Эта функция имеет структуру wait() -> critical section -> signal(). В ожидании, если кто-то еще пишет, я еще (еще не сделал) приостановил поток, чтобы пользователь не дождался, пока он закончит писать.

У меня есть два вопроса:

  1. Как реализовать мьютекс (блокировка функции)? Я понимаю, что это должна быть атомная функция, смысл нескольких потоков, пытающихся получить блокировку, может привести к хаосу.
  2. Является ли моя общая структура правильной?

Я новичок в параллелизме и буду благодарен за любые мысли по этому вопросу - спасибо!

+1

Вы должны добавить тег, соответствующий используемому вами языку (например, C или C++). Это привлечет больше просмотров => больше ответов. – assylias

+3

Вам было бы лучше отталкивать структуры 'Task' до очереди/вектора и обрабатывать их последовательно из одного потока вместо нескольких потоков для каждой задачи по отдельности. Единственное место, где вам понадобится мьютекс, - это нажать на очередь. – irobot

+0

@IRobot, это хороший ответ – Ben

ответ

4

Настройте структуры Task в очередь/вектор и обрабатывайте их последовательно из одного потока вместо нескольких потоков для каждой задачи отдельно. Единственное место, где вам понадобится мьютекс, - это нажать и вытащить из очереди. Как правильно заметил Бен в комментариях, вы должны оставить реализацию примитивов синхронизации потоков (мьютекса, критического раздела) для ОС и/или любого системного API, который вы разрешили использовать.

+1

Правильный подход, безусловно. Создание нового потока для каждой записи - вот такая плохая идея, что я задаюсь вопросом, откуда она взялась. Где-то есть учебник или набор того же самого, который гласит: «Чтобы использовать потоки, вы должны создать его с вашими данными в качестве параметра, позволить ему работать, а затем разрешать его завершать, возвращаясь. Для бонусных баллов используйте «join», чтобы добавить еще больше накладных расходов на ваше приложение ». Кто-нибудь, пожалуйста, соберет все эти учебники и сожжет их, предпочтительно сложенные вокруг долей с привязанными к ним авторами. –

Смежные вопросы