Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Чтение фалов несколькими потоками thread 
:(
    Опции темы
chetl
Дата 28.10.2016, 07:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 12.9.2007

Репутация: нет
Всего: нет



Есть папка с 40 тысячами файлов. Необходимо считать их несколькими потоками. То как вижу реализацию программы я это сначала найти все 40 тыщ файлов, записать их адреса в вектор, а потом передать работу с ними четырем потокам, но хотелось бы распараллелить эту работу, если у меня  4 потока то для их работы нужно только 4 файла а не все 40 тыщ. Как сделать чтобы программа параллельно искала файлы и в тоже время найденные файлы обрабатывали потоки, а не сначала искать все файлы а потом их обрабатывать?
Вот например чтение одного файла одним потоком
Код

void worker (const string& filename) {
      // open the file and seek end
      ifstream file(filename, ios::binary|ios::ate);
      // print current position (equal file size in bytes)
      cout << file.tellg();
}
int main () {
   thread t(worker, "file.txt");
   t.join();
}

вот поиск файлов в папке
Код

#include <stdio.h>
#include <windows.h>
 
int main()
{
    Vector<TCHAR> myVector;
    HANDLE handle;
    WIN32_FIND_DATA findData;
 
    handle = FindFirstFile("D:\\*.txt", &findData);
    if (handle == INVALID_HANDLE_VALUE)
        return 1;
 
    do
    {
        myVector .push_back(findData.cFileName);
    }
    while (FindNextFile(handle, &findData) != 0);
    FindClose(handle);
    
    return 0;
}



Это сообщение отредактировал(а) chetl - 28.10.2016, 10:04
PM MAIL   Вверх
xvr
Дата 28.10.2016, 13:58 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Делаете очередь (с блокировками по чтению), далее запускаете ваши 4 потока, которые читают из очереди по 1 элементу (имя файла) и обрабатывают. И последний (точнее первый) поток (основная программа) занимается сканированием папки и складыванием имен файлов в очередь.

Сама очередь выглядит как то так:
Код

//---------------------------------------------------------------------------

#ifndef queueH
#define queueH
//---------------------------------------------------------------------------
#include <deque>

template<class Item>
class WQueue {
 std::deque<Item> queue;

 CRITICAL_SECTION cs;
 HANDLE sema;
 HANDLE not_emp_sig;

public:
 WQueue(int max_size)
  {
   sema=CreateSemaphore(NULL,max_size,max_size,NULL);
   not_emp_sig=CreateEvent(NULL,FALSE,FALSE,NULL);
   InitializeCriticalSection(&cs);
  }
 ~WQueue()
  {
   CloseHandle(sema);
   CloseHandle(not_emp_sig);
   DeleteCriticalSection(&cs);
  }

 void put(const Item& it)
  {
   WaitForSingleObject(sema,INFINITE);
   EnterCriticalSection(&cs);
   queue.push_back(it);
   SetEvent(not_emp_sig);
   LeaveCriticalSection(&cs);
  }

 Item get()
  {
   for(;;)
    {
     WaitForSingleObject(not_emp_sig,INFINITE);
     EnterCriticalSection(&cs);
     if (queue.empty())
      {
       LeaveCriticalSection(&cs);
       continue;
      }
     Item rv=queue.front();
     queue.pop_front();
     if (!queue.empty()) SetEvent(not_emp_sig);
     ReleaseSemaphore(sema,1,NULL);
     LeaveCriticalSection(&cs);
     return rv;
    }
  }

 size_t get_cur_size()
  {
   EnterCriticalSection(&cs);
   size_t rv=queue.size();
   LeaveCriticalSection(&cs);
   return rv;
  }

};

#endif
В вашем случае будет WQueue<std::string>

PM MAIL   Вверх
chetl
Дата 28.10.2016, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 12.9.2007

Репутация: нет
Всего: нет



Разобрался сам написав свой код. Реализовал предложенную идею с потокобезопасными очередями. 
Выглядит это так:
Код

template<typename T>
class MyQueue
{
private:
    std::queue<T> queue_;
    std::mutex mutex_;
    std::condition_variable condition_;
public:
    void push(T const& item)
    {
        std::unique_lock<std::mutex> mlock(mutex_);
        queue_.push(item);
        mlock.unlock();
        condition_.notify_one();
    }

    T pop(void)
    {
        std::unique_lock<std::mutex> mlock(mutex_);
        while(queue_.empty())
        {
            condition_.wait(mlock);
        }
        auto  popped_value=queue_.front();
        queue_.pop();
        return popped_value;
    }
    
};


Это сообщение отредактировал(а) chetl - 29.10.2016, 07:23
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1100 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.