Форвардное объявление является признаком отсутствующих модулей в C ++ (будет исправлено в C ++ 17?) И использованием включения заголовков, если в C ++ были модули, то вообще не было необходимости в форвардных декларациях.
Форвардное объявление не меньше, чем «контракт», используя его , вы фактически обещаете , что обеспечите реализацию чего-либо (после того же в том же исходном файле или позже связав двоичный файл) .
Минусы этого в том, что вы на самом деле должны следовать вашему контракту , не так уж и много проблем, потому что, если вы не будете следовать своему контракту, компилятор будет как-то жаловаться раньше, но в некоторых языках код просто выполняются без необходимости «обещать свое существование» (говоря о динамически типизированных языках)
Я никогда не слышал, чтобы кто-нибудь использовал набор задач для увеличения производительности с Python. Это не значит, что этого не может произойти в вашем случае, но обязательно опубликуйте свои результаты, чтобы другие могли критиковать ваши методы тестирования и обеспечивать валидацию.
Лично я бы отделил ваши потоки ввода-вывода от потоков, связанных с процессором, используя очередь сообщений. Таким образом, ваш интерфейс теперь полностью привязан к сетевому вводу / выводу (некоторые с интерфейсом HTTP, некоторые с интерфейсом очереди сообщений) и идеально подходят для вашей ситуации с потоками. Тогда процессы, интенсивно использующие ЦП, могут либо использовать многопроцессорность, либо быть отдельными процессами, ожидающими поступления работы в очередь сообщений.
В более долгосрочной перспективе вы также можете подумать о замене интерфейса потокового ввода-вывода на Twisted или что-то еще. такие как eventlets , потому что, даже если они не улучшат производительность, они должны улучшить масштабируемость. Теперь ваша серверная часть уже масштабируется, потому что вы можете запускать свою очередь сообщений на любом количестве машин + процессор по мере необходимости.
На протяжении многих лет я обнаружил следующее практическое правило: если рабочие зависят от некоторого общего состояния, я использую один многопроцессорный процесс на каждое ядро (привязанный к ЦП), а на каждое ядро исправить пул рабочих потоков (привязка ввода / вывода). ОС позаботится о назначении различных процессов Python ядрам.
Другое решение: http://docs.python.org/library/multiprocessing.html
Примечание 1: Это не ограничение языка Python, а ограничение реализации CPython.
Примечание 2 : Что касается привязки, у вашей ОС не должно быть проблем с этим.
Python GIL предназначен для интерпретатора Python. Это означает, что единственное, чтобы избежать проблем с этим при выполнении многопроцессорной обработки, - это просто запустить несколько интерпретаторов (т.е. использовать отдельные процессы вместо потоков для параллелизма), а затем использовать какой-либо другой примитив IPC для связи между процессами (например, сокеты). При этом GIL не является проблемой при использовании потоков с блокирующими вызовами ввода-вывода.
Основная проблема GIL, как упоминалось ранее, заключается в том, что вы не можете выполнять 2 разных потока кода Python одновременно. Блокировка потока при вызове блокирующего ввода-вывода блокируется и, следовательно, не выполняет код Python. Это означает, что он не блокирует GIL. Если у вас есть две задачи с интенсивным использованием ЦП в отдельных потоках python, именно здесь GIL убивает многопроцессорность в Python (только реализация CPython, как указывалось ранее). Поскольку GIL не позволяет ЦП № 1 выполнять поток Python, в то время как ЦП № 0 занят выполнением другого потока Python.
Until such time as the GIL is removed from Python, co-routines may be used in place of threads. I have it on good authority that this strategy has been implemented by two successful start-ups, using greenlets in at least one case.