Там какие-либо практические альтернативы к потокам?

При чтении на SQLite, я наткнулся на эту кавычку в FAQ: "Потоки являются злыми. Избегайте их".

Я испытываю большое уважение к SQLite, таким образом, я не мог просто игнорировать это. Я получил взгляды, что еще я, согласно "избегаю их" политика, мог использовать вместо этого для параллелизации моих задач. Как пример, приложение, я в настоящее время продолжаю работать, требует пользовательского интерфейса, который является всегда быстро реагирующим, и должен время от времени опрашивать несколько веб-сайтов (процесс, который занимает по крайней мере 30 секунд для каждого веб-сайта).

Таким образом, я открыл PDF, связанный от того FAQ, и по существу кажется, что бумага предлагает, чтобы несколько методов были применены вместе с потоками, такими как барьеры или транзакционная память - а не любые методы для замены потоков в целом.

Учитывая, что эти методы не полностью обходятся без потоков (если я не неправильно понял то, что газета сообщает), я вижу две опции: или FAQ SQLite буквально не означает то, что он говорит, или там существуйте практические подходы, которые на самом деле избегают использования потоков в целом. Есть ли кто-либо?


Просто быстрое примечание по tasklets/cooperative, планирующему как альтернатива - это выглядит большим в небольших примерах, но интересно, может ли большой выход тяжелое UI приложение быть практически параллелизирован только совместным способом. Если Вы сделали это успешно или знаете о таких примерах, это, конечно, квалифицирует как действительный ответ!

12
задан Roman Starkov 15 January 2010 в 00:07
поделиться

12 ответов

Примечание : Этот ответ больше не точно отражает то, что я думаю об этой теме. Мне не нравится его чрезмерно драматичный, несколько противный тон. Кроме того, я не очень уверен, что квест к доскоре правильному программному обеспечению был настолько бесполезен, насколько я, казалось, думал тогда. Я покидаю этот ответ, потому что он принят, и проголосовал, и редактировать его в то, что я в настоящее время верю, что будет в значительной степени вандализовать его.


Я наконец вернулся на чтение бумаги. Где я начинаю?

Автор поет старую песню, которая идет что-то подобное: «Если вы не можете доказать, что программа верна, мы все обречены!» Это звучит лучше всего, когда он громко закричал в сопровождении над модулированными электрогитарами и быстрым ударным барабаном. Академики начали петь эту песню, когда компьютерная наука была в области математики, мир, где, если у вас нет доказательства, у вас ничего нет. Даже после того, как первый отдел компьютерных наук был расщеплен от отдела математики, они продолжали петь эту песню. Они поют эту песню сегодня, и никто не слушает. Почему? Потому что остальные из нас заняты созданием полезных вещей, хорошие вещи из программного обеспечения, которые не могут быть доказаны правильными.

Наличие нитей делает его еще сложнее, чтобы доказать программу правильной, но кто заботится? Даже без потоков только самые тривиальные программы могут быть доказаны правильными. Почему мне все равно, если моя нетривиальная программа, которая не может быть доказана правильной, еще более неоправданна после использования резьбы? Я не.

Если бы вы не были уверены, что автор жил в академическом Dreamworld, вы можете быть уверены в этом после того, как он утверждает, что языком координации он предлагает как альтернатива потокам, можно лучше выразить с помощью «визуального синтаксиса» (рисунок Графики на экране). Я никогда не слышал это предложение раньше, кроме каждого года моей карьеры. Язык, который можно манипулировать только GUI и не играет только с обычными инструментами программиста, не является улучшением. Автор продолжает цитировать UML как яркий пример визуального синтаксиса, который «регулярно сочетается с C ++ и Java». Маргетически в каком мире?

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

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

6
ответ дан 2 December 2019 в 05:54
поделиться

Зло, но необходимое зло. Абстракции высокого уровня нитей (задачи в .NET Например) становится все более распространенным, но по большей части промышленность не пытается найти способ избежать нитей, просто облегчает дело с сложностями, которые приходят с любым видом одновременное программирование.

2
ответ дан 2 December 2019 в 05:54
поделиться

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

-121--3456797-

Спасибо за оба ответа. Я объединил оба ваших ответа в одно... свойство с таким фильтром:

 def _get_blue_shirts(self):
  if self.shirtclr.filter(shirtcolor='Blue'):
   return '%s%s' % ('B', self.shirtmodel)
  else:
   return self.shirtmodel
 blue_shirts=property(_get_blue_shirts)

Хотя этот подход определенно работает, я вижу проблемы с ним, как я написал его. Во-первых, я хотел бы найти в admin с, например, «B13A» в качестве модели рубашки и понять, что я имею в виду «13A» рубашка доступна с Blue в качестве одного из его цветов. Поскольку ModelAdmin.search_fields, по-видимому, необходимо перейти к фактическому полю, этот подход не работает в этом отношении (исправьте меня, если я там не прав). Другая проблема, которую я имею, заключается в том, что свойство кажется очень тяжелым для SQL... выполнение отдельного выбора для каждой строки (в то время как выделенному столбцу просто нужен общий выбор... снова, исправьте меня, если я не прав). Есть идеи, как я могу решить эти проблемы? Возможно, я мог бы пойти по этому пути?

PS. Энтони... Я попробовал переработанный переопределенный save () и все еще получил экземпляр "" ShirtClass "" должен иметь значение первичного ключа, прежде чем отношение "многие ко многим" может быть использовано "ошибка. Я делаю что-то не так здесь?

Многие, многие, большое спасибо всем, -bkev

-121--4196174-

Альтернативы потокам:

  • coroutines
  • goroutines
  • mapreduction
  • workpool
  • яблок grand central dispatch + lambdas
  • openCL
  • erlang

(интересно отметить, что половина этих технологий была изобретена или популяризирована google).

Другое дело, что многие веб- рамки прозрачно используют несколько потоков/процессов для обработки запросов, и обычно в таком пути, которая в основном устраняет проблемы, связанные с многопоточностью (для пользователя рамки) или, по крайней мере, делает многопоточность довольно невидимой. Веб-сайт не имеет состояния, единственным общим состоянием является состояние сеанса (что на самом деле не является проблемой, так как по определению один сеанс не будет выполнять параллельные операции), и данные в базе данных, которая уже имеет свой многопоточный нонсенс разобраны для вас.

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

2
ответ дан 2 December 2019 в 05:54
поделиться

Если ваша задача действительно, действительно легко isolatable, вы можете использовать процессы вместо потоков, таких как Chrome делает для его вкладок.

В противном случае в одном процессе нет способа добиться реального параллелизма без потоков, поскольку вам нужно как минимум два COROTOUTINES, если вы хотите, чтобы две вещи были одновременно (при условии, что у вас есть несколько процессоров / ядер в Рука, конечно; в противном случае реальные параллелизм просто невозможно).

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

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

1
ответ дан 2 December 2019 в 05:54
поделиться

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

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

1
ответ дан 2 December 2019 в 05:54
поделиться

Вы также можете присоединиться к проекту Robocode и реализовать некоторую нетривиальную функцию ;-) Прочитайте это и Поговорим с нами .

-121--1278822-

Одной из тенденций, которую я заметил, по крайней мере, в домене Cocoa, это помогает из структуры. Apple пошел на большую длину, чтобы помочь разработчикам с относительно сложной концепцией одновременного программирования. Некоторые вещи, которые я видел:

  • разная гранулярность резьбы. Cocoa поддерживает все из потоков POSIX (низкий уровень), чтобы объектно-ориентированную резьбу с NSLock и NSTHOAD, к высокоуровневой пареллелизме, таком как NSOPERIENT. В зависимости от вашей задачи, использование высокоуровневого инструмента, такого как NSOperation, легче и получает выполнение работы.

  • резьба за кулисами через API. Многие пользовательские и анимационные материалы в какао спрятаны за API. Вы несете ответственность за вызование метода API и предоставление асинхронного обратного вызова, которое выполняется, когда вторичный поток завершается (например, конец некоторой анимации).

  • OpenMP. Есть такие инструменты, как OpenMP, которые позволяют предоставлять прагами, которые описывают компилятору, что некоторая задача может быть безопасно разрешено. Например, итерация набора элементов независимым способом.

Похоже, что большой толчок в этой отрасли состоит в том, чтобы сделать все возможное для разработчиков приложений и оставить детали потока горы в разработчиков системы и разработчикам каркаса. Есть толчок в академии для формализации шаблонов рассеяния. Как уже упоминалось, вы не всегда можете избежать резьбы, но в вашем арсенале есть все больше инструментов, чтобы сделать его как можно более безболезненным.

2
ответ дан 2 December 2019 в 05:54
поделиться

Если вы действительно хотите жить без потоков, вы можете, до тех пор, пока вы не называете какие-либо функции, которые могут потенциально блокировать. Это может быть невозможно.

Одной из альтернативы является реализация задач, которые вы сделали в потоках как конечных станков . В основном задача делает то, что она может сделать немедленно, затем идет к своему следующему состоянию, ожидая события, такого как ввод, прибывающий на файл или таймер. X Windows, а также большинство инструментов GUI, поддерживают этот стиль. Когда что-то происходит, они называют обратным вызовом, что делает то, что ему нужно делать и возвращать. Для FSM обратный вызов проверяет, как посмотреть, в каком состоянии является задача, и что это должно определить, что будет немедленно и то, что будет следующее состояние.

Скажем, у вас есть приложение, которое необходимо принять соединения сокетов, и для каждого соединения, анализа командных строк, выполняйте какой-код и вернуть результаты. Задача тогда будет то, что слушает розетку. Когда выберите () (или GTK +, или что-то еще), говорит вам, что сокет имеет что-то прочитать, вы прочитаете его в буфер, затем проверьте, если у вас есть достаточно ввода, чтобы сделать что-то. Если это так, вы продвигаетесь на «начать делать что-то», иначе вы остаетесь в состоянии «чтения строки». (Что вы «делаете», могут быть несколькими состояниями.) Когда сделано, ваша задача бросила линию из буфера и возвращается к состоянию «чтение строки». Никаких нитей или вытеснения не требуются.

Это позволяет действовать многопоточественным путем, по которым управляются событиями. Однако, если ваши штатные машины усложняются, ваш код может усердно поддерживать довольно быстро, и вам нужно будет работать какой-то библиотеку FSM-Management, чтобы отделить Грунтную работу запуска FSM из кода, который на самом деле делает вещи Отказ

P.S. Другим способом получения потоков без на самом деле используемых потоков является GNU PTH Library . Это не делает вытеснение, но это еще один вариант, если вы действительно не хотите иметь дело с потоками.

2
ответ дан 2 December 2019 в 05:54
поделиться

Операция в SQLite FAQ, как я ее прочитал, является всего лишь комментарием о том, насколько сложным может быть многопоточность для непосвященных. Это мнение автора, и оно может быть обоснованным. Но говорить, что никогда не следует использовать нити - это выбрасывать ребенка с водой в ванне, в моем мнении. Нитки - это инструмент. Как и все инструменты, их можно использовать, и ими можно злоупотреблять. Я могу прочитать его статью и убедиться, что нити - это дьявол, но я успешно использовал их, без убийства котят.

Имейте в виду, что SQLite написан так, чтобы быть как можно более легким и понятным (с точки зрения кодирования), поэтому я представляю, что нити - это своего рода антитеза этому легковесному подходу.

Кроме того, SQLite не предназначен для использования в сильно текущей среде. Если у вас есть такая база данных, то, возможно, вам лучше работать с более корпоративной базой данных, такой как Postgres.

5
ответ дан 2 December 2019 в 05:54
поделиться

Потоки - не единственная модель параллелизма. Модель акторов (Эрланг, Скала) является примером несколько иного подхода.

http://www.scala-lang.org/node/242

1
ответ дан 2 December 2019 в 05:54
поделиться

Одним из способов избежать потоков является мультиплексирование - в сущности, вы делаете легкий механизм, похожий на потоки, которыми вы управляете сами.

Дело в том, что это не всегда осуществимо. В вашем случае время опроса 30s на сайт - можно ли его разделить на 60 0.5s штук, между которыми можно запихивать звонки в пользовательский интерфейс? Если нет, извините.

Нитки - это не зло, они просто легко простреливают вам ногу. Если выполнение Запроса A занимает 30 секунд, а затем выполнение Запроса B занимает еще 30 секунд, то одновременное выполнение их в нитях займет 120 секунд вместо 60 из-за накладных нитей, борьбы за доступ к диску и различных узких мест.

Но если операция A состоит из 5 с и 55 секунд ожидания, смешивается случайным образом, и операция B занимает 60 с фактической работы, то выполнение их в потоках займет, может быть, 70 с, по сравнению с обычными 120, когда вы выполняете их последовательно.

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

.
0
ответ дан 2 December 2019 в 05:54
поделиться

Насколько мне известно, iSimulate не использует никаких взломов. Это код, который запускается в вашем приложении на симуляторе и взаимодействует с устройством по сети. Когда он получает сообщения от устройства (касания, GPS, ускорение), он имитирует эти события, вызывая код вашего приложения, как будто система запустила их.

Например, для получения обновлений местоположения GPS необходимо создать экземпляр CLLocityManager, а затем настроить один из классов в качестве его делегата. Ну, на iPhone Simulator можно вместо этого запустить код, который отправляет фальшивые сообщения делегату. Если вы просто вызовете метод делегата так:

[delegate locationManager:nil didUpdateToLocation:newLocation fromLocation:oldLocation];

Ваш код не должен будет знать, что обновление местоположения поддельное. Если вы хотите получить фантазии, вы можете создать новый класс, который реализует все общедоступные методы CLLocityManager, но который отправляет фальшивые сообщения. (Поскольку Objective-C набирается динамически, он не должен быть подклассом, если он отвечает на все отправляемые сообщения.)

В качестве побочного примечания можно использовать эти макросы компилятора, чтобы сохранить только симулятор кода:

#if TARGET_IPHONE_SIMULATOR
   locationManager = (id)[[MyFakeLocationManager alloc] init];
#else
   locationManager = [[CLLocationManager alloc] init];
#endif
-121--1547410-

Возможно, вы могли бы попробовать VTD light Он кажется более эффективным по сравнению с SAX. (Я знаю, что это огромное изменение.)

-121--2733384-

Другой подход к этому может заключаться в использовании другой модели параллелизма вместо того, чтобы вообще избегать многопоточности (необходимо использовать все эти ядра ЦП параллельно каким-либо образом).

Просмотрите механизмы, используемые в Clojure (например, агенты , программных обеспечений память транзакций ).

2
ответ дан 2 December 2019 в 05:54
поделиться

Программная транзакционная память ( STM ) является хорошей альтернативой для управления параллелизмом. Он хорошо масштабируется с несколькими процессорами и не имеет большинства проблем традиционных механизмов управления параллелизмом. Он реализован как часть языка Haskell . Стоит попробовать. Хотя я не знаю, как это применимо в контексте SQLite.

2
ответ дан 2 December 2019 в 05:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: