Название: Бросает исключение в потоке Отправлено: blood_shadow от Апрель 20, 2011, 20:12 Вот только недавно начал шариться с потоками и попал на такую ситуацию:
есть поток с такой ф-цией run: Код
run() - запускается с конструктора данного объекта и останавливается (filesAdded.wait(&filesReadMutex)) когда readFilesQueue - очередь пуста и есть ф-ция для добавления в очередь: Код
после добавления больших файлов где-то 300Мб на втором из них программа завершается с ошибкой(Invalid parameter passed to C runtime function.) и более того она кидает исключение std::bad_alloc, происходит это в районе ф-ции listOfEncodedFiles->append(file.readAll().toBase64()); listOfEncodedFiles - указатель на список кодированных строк, если же добавлять маленькие файлы то все нормально, в чем может быть проблема? Название: Re: Бросает исключение в потоке Отправлено: Sancho_s_rancho от Апрель 20, 2011, 20:54 На первый взгляд все нормально. Вы пытаетесь загрузить 300 мб в память(да еще и несколько таких файлов), и перекодировать в base64(на это тоже нужно место). В результате вы получаете исключение "не могу выделить память". Вполне ожидаемое поведение. Обычно десятки мегабайт не грузят в память, а пользуются mapping-ом (как по русски я не знаю).
Посмотрите сюда http://labs.qt.nokia.com/2007/10/15/file-mapping/ Название: Re: Бросает исключение в потоке Отправлено: blood_shadow от Апрель 20, 2011, 22:25 На первый взгляд все нормально. Вы пытаетесь загрузить 300 мб в память(да еще и несколько таких файлов), и перекодировать в base64(на это тоже нужно место). В результате вы получаете исключение "не могу выделить память". Вполне ожидаемое поведение. Обычно десятки мегабайт не грузят в память, а пользуются mapping-ом (как по русски я не знаю). понял идею маппинга, но вот стало интересно почему когда у меня был один потокПосмотрите сюда http://labs.qt.nokia.com/2007/10/15/file-mapping/ при таком же занимаемом количестве памяти не вылетало исключение? Название: Re: Бросает исключение в потоке Отправлено: Igors от Апрель 21, 2011, 10:47 Не знаю подробностей задачи, поэтому рекомендации ниже "общие"
1) wait/wakeOne(All) достаточно трудно и ошибиться здесь легко, напр Код это запросто может повесить задачу. Во многих случаях семафор лучше и гораздо проще для понимания 2) readAll конечно очень удобная ф-ция но так мы расписываемся что "извините, с большими файлами мы не работаем" 3) маппинг файлов - палка о 2 концах, самое неприятное что поведение может быть очень разным на разных платформах и даже версиях ОС. Всегда есть вероятность положить систему намертво, и она далеко ненулевая 4) Хорошим стилем считается обработка файла по частям неск. нитками с управляемым размером буфера Название: Re: Бросает исключение в потоке Отправлено: blood_shadow от Апрель 21, 2011, 11:37 1) wait/wakeOne(All) достаточно трудно и ошибиться здесь легко, напр Код это запросто может повесить задачу. Во многих случаях семафор лучше и гораздо проще для понимания можете объяснить почему там пробой? я же защитил данный участок кода мьютексом: Код
и чем в данном случае семафор лучше мьютекса если я пытаюсь предоставлять доступ только одному потоку? Название: Re: Бросает исключение в потоке Отправлено: blood_shadow от Апрель 21, 2011, 11:40 4) Хорошим стилем считается обработка файла по частям неск. нитками с управляемым размером буфера понял, вопрос - файл разбивается на части с точки зрения размера или количества ниток или жес установленного размера буфера? Название: Re: Бросает исключение в потоке Отправлено: Igors от Апрель 21, 2011, 12:49 можете объяснить почему там пробой? я же защитил данный участок кода мьютексом: Пусть 2 (или более) ниток стоят на wait. Хорошо, Вы положили в очередь 10 fileNames и вызвали wakeOne. Одна из ожидающих пошла молотить, а остальные? Стоят. Вроде вместо wakeOne надо wakeAll но тогда др. заморочка - а вдруг число ожидающих больше числа задач и развалимся на dequeue? Может я и неправ, но (во всяком случае для меня) это головоломка :)и чем в данном случае семафор лучше мьютекса если я пытаюсь предоставлять доступ только Не лучше но куда проще. Положили 10 задач, сказали семафору release(10), а извлекающие просто вызывают acquire. Остается только защитить enqueue/dequeue мутексомодному потоку? понял, вопрос - файл разбивается на части с точки зрения размера или количества ниток или же Задаем (возможно спрашивая у пользователя) общий размер используемой памяти и распределяем его между нитками. Число ниток - в большинстве случаев число ядер + 1 (главная).с установленного размера буфера? Название: Re: Бросает исключение в потоке Отправлено: blood_shadow от Апрель 21, 2011, 14:01 Не лучше но куда проще. Положили 10 задач, сказали семафору release(10), а извлекающие просто вызывают acquire. Остается только защитить enqueue/dequeue мутексом это я виноват, не указал что у меня только два потока(главный + FilesAttachementManage), проектировалосьизначально на 2 потока, потому мьютекс тут только защищает от вмешивание главного потока по добавлению в очередь. В данном случае wakeOne(); может пробудить только вторичный поток, использовать же wakeOne(); для пробуждения какого-нибудь из многих потоков упаси Господи :) Задаем (возможно спрашивая у пользователя) общий размер используемой памяти и распределяем его между нитками. Число ниток - в большинстве случаев число ядер + 1 (главная). а если программа предназначается на общак, то есть мы число ядер будет разным,а возможно и ОС будут разными, какими соображениями руководится? Название: Re: Бросает исключение в потоке Отправлено: Igors от Апрель 21, 2011, 14:31 это я виноват, не указал что у меня только два потока(главный + FilesAttachementManage), проектировалось Пока Вы это писали, раз 5 можно было поменять на семафор и забыть о "проектировании на 2 потока" :)изначально на 2 потока, потому мьютекс тут только защищает от вмешивание главного потока по добавлению в очередь. В данном случае wakeOne(); может пробудить только вторичный поток, а если программа предназначается на общак, то есть мы число ядер будет разным, Число ядер везде известно/определяется (в Qt, насколько помню, idealThreadCount)а возможно и ОС будут разными, какими соображениями руководится? Название: Re: Бросает исключение в потоке Отправлено: CL0NE от Апрель 21, 2011, 15:50 Цитировать использовать же wakeOne(); для пробуждения какого-нибудь из многих потоков упаси Господи wake* будит только те потоки, которые на это условие ожидают.Название: Re: Бросает исключение в потоке Отправлено: Igors от Апрель 21, 2011, 18:10 Мелочь, но может пригодится: а как будете завершать рабочую нитку(и)? (есть хороший способ :))
Название: Re: Бросает исключение в потоке Отправлено: blood_shadow от Апрель 29, 2011, 17:19 Положили 10 задач, сказали семафору release(10), а извлекающие просто вызывают acquire. Остается только защитить enqueue/dequeue мутексом а как создать много одинаковых потоков с общим семафором? |