2012-05-09 2 views
0

Рассмотрим следующую примерную программу, в которой работает цикл;C++ thread concept

int main() 
{ 

    for (int i = 0; i<= 300; ++i) { 

    } 

} 

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

cout << "i= " << i << "\n"; 

Простой цикл, как следующий может быть достаточно, где «elaspedTime» является вымышленной целое число, содержащее количество секунд программа работает волшебно обновляется ОС:

int lastTime = 0; 
while (true) { 
    if (elapsedTime > lastTime) { // Another second has passed 
    cout << "i= " << "\n"; 
    lastTime = elapsedTime; 
    } 
} 

конечная цель здесь, чтобы дать выход вроде следующего (Ассу мина петля побежал ровно 100 раз в секунду, потому что это было на старом, медленном CPU):

$ ./myprog 
i= 100 
i= 200 
i= 300 

Эти простые функции и процедуры, несмотря на это, я не вижу никакой возможности выполнить такую ​​операцию в «классической «C++-программа, которая обычно имеет только функцию main(). Несмотря на простоту, это тот момент, когда мне нужно изучить многопоточность? Или, возможно ли вызывать функции от main() и не дожидаться их возврата, но без этой вызываемой функции «hogging» поток?

+0

Мне что-то не хватает. Я не понимаю, как это связано с потоками. Похоже, вам просто нужна функция «сна» (если, конечно, другая обработка занимает значительное время, и в этом случае вам понадобятся функции времени, чтобы выяснить, как долго спать и т. Д.) –

+1

Вам не требуется многопоточность Вот. Когда вам понадобится многопоточность, вы это узнаете. –

+0

Извините, мне показалось, что я понял, что хочу, чтобы все это происходило одновременно с 'main()'. Это, по существу, две петли, работающие независимо друг от друга, одна распечатывает результаты другой. Это ясно? – jwbensley

ответ

1

Что не так с этим? Не требуется многозадачность.

int lastTime = 0; 
while (true) { 
    if (std::time() > lastTime) { // Another second has passed 
    cout << "i= " << i << "\n"; 
    // potentially expensive code goes here, which updates "i" 
    lastTime = std::time(); 
    } 
} 
+0

Извините, возможно, я не был ясен. Как все, что происходит в одном потоке, в вашем предположении «i» не увеличивается? – jwbensley

+0

Это * есть * все происходит в одном потоке. Или вы спрашиваете, как запустить этот цикл одновременно с циклом 'for' в главном? –

+0

Ах да, я вижу сейчас, мне просто нужно перестроить порядок событий в цикле. Спасибо: D – jwbensley

3

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

Многопоточность - это то, что не упоминается в стандарте C++ 03. В последней версии C++ 11 есть определенная поддержка, но это не конец, все. Способ многопоточности фактически реализован для платформы. Коробки WinTel делают это в одну сторону, а ящики Linux/Intel делают это другое. Двумя основными подходами к написанию многопоточного кода являются:

  1. Используйте специфичные для платформы средства.
  2. Используйте кросс-платформенную библиотеку потоков.

Когда я только начинаю, в эти дни я бы посоветовал начать с кросс-платформенной библиотеки, чтобы вы могли использовать многие из концепций большой картины, не увязавшись с особенностями конкретной платформы. Одна такая библиотека - Boost.Thread.

EDIT

Учитывая, что вы новичок в mutithreaded программирования, я чувствую, что я должен вас предупредить: вы спрыгнув глубокую кроличью нору с завязанными глазами. Многопоточное программирование похоже на шахматы - вы можете очень быстро узнать основную синтаксическую и системную вызовы, но многопоточное программирование - это то, что будет доступно только с лотом обучения и практики. Многопотоковое программирование, выполненное правильно, является одной из самых сложных задач, с которыми программист сталкивается.

Кроме того, обратите особое внимание на @ комментарий CrazyEddie в поле ниже:

После перехода из «функции» в «задачи», хотя история изменений. Вполне возможно выполнить множество задач сразу, в зависимости от задачи. Поскольку циклы событий, подобные OP, обычно проводят большую часть времени спальные, потоки обычно используются только для удобства, а не для производительности или необходимости. Я уверен, что вы это знаете, но OP, вероятно, этого не делает. OP необходимо искать «асинхронную обработку» и взвешивать преимущества/штрафы за использование потоков против неблокирующих операций и событий .

+1

Как только вы переключаетесь с «function» на «task», хотя история меняется. В зависимости от задачи можно выполнить сразу несколько задач сразу. Поскольку циклы событий, подобные OP, обычно проводят большую часть времени сна, потоки обычно используются только для удобства, а не для производительности или необходимости. Я уверен, что вы это знаете, но OP, вероятно, этого не делает.OP необходимо искать «асинхронную обработку» и взвешивать преимущества/штрафы за использование потоков против неблокирующих операций и циклов событий. –

+0

@CrazyEddie: Согласен - я отредактирую и включу ваши комментарии. –

+0

Это действительно отличный ответ, спасибо вам за ваш обширный и подробный ответ. Это дало мне много, чтобы думать и читать, спасибо :) – jwbensley

0

Мне любопытно, какую проблему вы пытаетесь решить, хотя. Откуда взялось «желание узнать, сколько итераций сделано за секунду»? Причина, о которой я спрашиваю, заключается в том, что ответ, который вы получите, используя один подход к потоку, рассмотренный наверху (проверка часов - инкремент - проверка часов - увеличение ... проверка часов - печать) или многопоточный подход, они обе страдают от введения накладных расходов и неопределенности в работе вашего потока. Я имею в виду: в обоих случаях вам придется выполнять кучу дополнительных вызовов stuff - clock() в одном потоке и синхронизации потоков в многопоточном случае. Оба будут влиять на общее количество итераций, выполненных за секунду вашей программой (число будет меньше), поэтому вы получите неверный результат. Кроме того, в качестве операционной системы используется планировщик потоков Whats, когда ваш поток работает и когда он спит, ожидая следующего доступного кванта. И квант ~ 20-30 миллисекунд, поэтому результирующая ошибка во время проверки временного интервала может легко (вероятно, в среднем) быть на несколько процентов.

Было бы проще и естественнее сохранить время начала, а затем выполнить все итерации, необходимые вам для обработки всех ваших данных (выполнить всю работу), затем снова взять временную метку и разделить общее количество итераций по временному интервалу. Или есть что-то конкретное для проблемы, которую вы решаете, что этот подход не сработает?