Как стать автором
Обновить

Комментарии 61

Я думаю я тут выскажу основную идею всех последующих комментов.
А почему не Кьют?
А почему куте? На нем, что свет клином сошелся?
ну в рамках гтк против кьюта, да, сошелся. Я честно не вижу преимуществ у гтк перед кьютом
Я сам не питаю любви к гтк, мне больше по душе wxWidgets. А конкретно по вашему замечанию, то у куте хорошая документация, много примеров лишний раз можно его и не упоминать.
Меня на самом деле волновал похожий вопрос но в более глобальном смысле, почему не C++?
Представленные здесь примеры, это не low level в котором важна скорость или требуется супер быстрая работа с сырыми данными (вопрос о том что С++ в большинстве случаев сделает все тоже самое, ничуть не хуже и не медленнее пока оставим в стороне), это крайне высокоуровневый код для работы с потоками и UI. Так зачем же себя мучить и оказываться от удобной реализации ООП парадигмы в лице С++? Зачем пародировать объекты с помощью структур и методов с монстроподобными названиями?
А я бы спросил — почему не boost? Тут вам и кросс-платформенность, и многопоточность, и очень хорошее апи, и частые релизы новых версий.
Общий недостаток Qt и Gtk- это фреймворки, а когда нужно что-то не столь тяжелое буст имхо подходит лучше.
Ну а уж если хотите потоки на чистом си то pthread вам в помощь. Для винды есть замечательный порт pthread-win32 а для других платформ они доступны нативно.
ну буст отличается тем, что там нет гуя. То есть его тут не очень корретктно притягивать. Буст кстати неплохо сочетается с кьютом в умелых руках
Ну так и топик не про гуи. При прочих равных буст лучше кьюта, а чистый с++ лучше буста. Поэтому в тему топика — с++11 и никаких глибов не надо.
ну честно говоря подумать про использование гтк без гуя мне как то и в голову не приходило. Это был бы очень странный шаг, не правда ли?
Мне в голову не приходит писать консольные приложения на кьюте, но их от этого писать не перестают. У каждого свои задачи. И автор писал конкретно про потоки, про гуи он не писал
Glib это не GTK, а вполне самостоятельная библиотека, например консольный midnight commander её использует.
НЛО прилетело и опубликовало эту надпись здесь
Ну вам же не 50 метров с собой таскать придется ;) нашли в чем буст упрекнуть
НЛО прилетело и опубликовало эту надпись здесь
А какие аргументы за то, чтобы класть буст в репозиторий?
НЛО прилетело и опубликовало эту надпись здесь
Пусть девелоперы сами ставят. Apt-get install boost.
НЛО прилетело и опубликовало эту надпись здесь
для буста есть bcp, если нужно вырезать что-то конкретное
Буст хорош модульностью — так для библиотеки с потоками вам потребуется собрать всего две либы — boost.thread и boost.system. Если же позже захотите добавить туда сокеты — то для boost.asio больше ничего собирать не придется. Все это добро будет выражаться в одном мегабайте библиотек. Впрочем, никто не заставлять таскать их с собой, когда можно собрать их как статические либы.
У меня, лично, сложилась чёткая позиция, что некоторые части QT пока малопригодны для интегрирования в кросс-платформенное ПО, но исключительно из-за проблем сообщества, там года два сейчас уйдёт на чистку и верификацию кода, а потом можно и пользоваться. Это только вопрос времени, но уже чётко были выделены ниши и для GTK, и для QT. Лично мне удобнее с GTK. Это точно так же, как Си / Си++: споры бесполезны, а знать надо и то и другое.
лолшто? Можно услышать какие именно части?
Или разговор идет про части QuickTime?
Не сложилось у меня, в своё время с QTsql*, для корректной сборки с близкими версиями glibc пришлось перекапывать исходники. Да и с QTcore, qtGUI проблем хватает, особенно, если работать с shared_lib, а не тупо вставлять в приложение для «кросс-платформенности». Кстати, тут тоже по сравнению c GTK сложностей больше (используя GTK, с mingw проще работать). Ну и память, память, память… Но всё же, с qt некоторые вещи можно сделать проще и быстрее.
знаете, вы один из тех немногих у кого постоянно что то не так с кьютом. Сколько им не пользуюсь никогда проблем не было. Ни под виндой, ни под линуксом, ни под маком, ни даже под линуксом на спарке
Нет, не постоянно, но было чаще, чем в GTK. Возможно это из-за малого опыта использования. Если бы я специализировался на GUI, то говорил бы, возможно, другое. Попытайтесь переписать статью, использовав QT… Вот тогда можно будет говорить о каком-то сравнении, а так это не true холивар, а словоблудие.
И из чистого опыта общения: Вы, наверное, зная (возможно очень большую часть) C++ даже не пробовали писать на чистом Cи? А то есть такая тенденция))
под кьют эту статью переписывать смысла нет. Это все разжевано в ассистанте.

Ну в свое время писал на чистом си, в том числе и в kernel-space
и перестаньте уже постоянно упоминать QuickTime
Кьют пишется Qt
Все части qt вполне пригодны. Они не лучшие в своем классе, но вполне пригодны.
Они сейчас сильно перекапываются. Можно, конечно использовать старые версии библиотек, но такой подход совсем не поможет в перспективе пары лет.
Имеется ввиду, что работа будет с shared библиотеками, из репов дистрибутива.
Внимание: Повторный вызов g_mutex_lock() внутри уже заблокированного мьютекса не заблокирует программу и будет просто проигнорирован, что защищает от повторных блокировок.

цитата из документации:
void g_mutex_lock(GMutex *mutex);

Locks mutex. If mutex is already locked by another thread, the current thread will block until mutex is unlocked by the other thread.

Note
GMutex is neither guaranteed to be recursive nor to be non-recursive. As such, calling g_mutex_lock() on a GMutex that has already been locked by the same thread results in undefined behaviour (including but not limited to deadlocks).
На практике происходит так: Если в одном и том же потоке заблокировать мьютекс через g_mutex_lock(), то повторные g_mutex_lock() в этом же потоке не приведут к блокировке. Другое дело, что потом придётся два раза разблокировать мьютекс. То есть вложенные мьютескы реально работают, но раз документация говорит, что это приводит к неопределённым результатам, видимо стоит избегать подобных ситуаций.
Это от платформы зависит… так что они верно пишут про неопределенное поведение. Так что мьютексы могут получиться как рекурсивными, так и нет.

Если разработка под заранее известные платформы, как это обычно бывает, то не страшно — можно заранее определиться с поведением, и защитить юнит тестами.

И для кросс-платформенной разработки неопределенное поведение не есть гут — источник багов и будущих проблем.
Внимание: Ожидание сигнала должно быть внутри заблокированного мьютекса, и посылать сигнал тоже рекомендуется внутри заблокированного мьютекса, хотя это и не обязательно.
Во время ожидания мьютекс временно разблокируется для того чтобы можно было зайти внутрь этого же мьютекса из другого потока и послать сигнал.

Рекомедую автору ознакомиться с темой condition variables, а то так сильно плавать в теме некрасиво.
А лучше, вместо троллинга(указание ошибки или псевдоошибки без уточнения верного ответа) написать ответ прямо в теме, что бы люди, которых заинтересовало, но которые еще не достаточно много знают, смогли бы найти ответ в комментариях. Что бы иметь общее представление о сути процесса и знали куда копать для более глубокого понимания.
а разве хабр не место для упражнений в троллинге? Чорт, а я то думал...
Для более глубокого понимания нужно копать по ключевым словам condition variable — это же очевидно)

Если вам так нужен мой пересказ текстбука – пожалуйста. В канонической системе три составляюшие: (1) мьютекс, (2) condition variable и (3) объект, целостность которого защищает мьютекс. Condition variable сигнализирует об изменении состояния этого объекта.

Если нам нужно дождаться, когда объект примет определенное состояние, делается это следующим образом. Перво-наперво лочим мьютекс, и проверям – может быть объект уже находится в нужном состоянии? Если нет, переходим к ожиданию сигнализации condition variable (мьютекс отпускается автоматически). Когда другой тред меняет состояние объекта, он также сперва лочит мьютекс, затем обновляет состояние объекта, затем сигналит condition variable, и наконец отпускает мьютекс. Первый тред просыпается, захватывает мьютекс, и проверяет новое состояние объекта. Если объект все еще не находится в нужном состоянии, повторяем все сначала.

Особое внимание стоит обратить на следующие моменты.
1. Мы всегда начинаем с проверки текущего состояния объекта. Поэтому не страшно, что мы потеряли все «сигнализации» condition variable, которые были до захвата мьютекса перед проверкой состояния объекта.
2. Когда мы переходим к ожиданию на condition variable, мьютекс отпускается автоматически. Важно, что это происходит атомарно — промежутка, когда мы уже отпустили мьютекс, но еще не ждем сигнализации condition variable, попросту нет.

А если бы был, в этот промежуток могли бы вклиниться другие треды — захватить мьютекс, изменить состояние объекта и просигналить, а мы бы ничего не заметили, потому что еще не перешли к ожиданию сигнализации.
Контрольные вопросы аудитории:
1) Можно ли использовать несколько condition variables в связке с единственным мьютексом?
2) Можно ли использовать один condition variable в связке с несколькими мьютексами?
1. да (не нашел в вашем пояснении запрета)
2. нет (атомарно отпустить несколько мьютексов проблематичным мне видится)

А вообще я здесь случайно, буквы знакомые ищу :)
Все верно)
А разве не так происходит?
Вот описание из документации: Atomically releases mutex and waits until cond is signalled.
А condition variables можно и не использовать.
Сравните ваше описание и мое.
condition variables — дополнительное средство синхронизации, на случай пропуска сигнала перед началом ожидания. Из за того что condition variables не были рассмотрены в статье, не значит что там что-то написано неправильно.
Ну вот вы опять фигню написали.
Что конкретно вы считаете неправильным? В противном случае это просто ничем не обоснованная критика. Может я чего-то и не понимаю, но все примеры были проверены практически.
«condition variables — дополнительное средство синхронизации, на случай пропуска сигнала перед началом ожидания» — вот это

GCond*, несправедливо обозванная вами «сигналом», это и есть condition variable.
Ясно, я то считал под condition variable — это переменная, изменение которой защищено мьютесом. Обычно g_cond_signal()/g_cond_wait() используется в связке с какой-нибудь переменной, но её может и не быть.

GCond*, несправедливо обозванная вами «сигналом», это и есть condition variable.
Так как нет перевода для средства синхронизации, вот и придумал более менее близкое по действию.
Мне всегда было любопытно — если в GTK чтобы отправить сообщение из рабочего потока в GUI штатным способом является вызвать «gtk_threads_add_idle()» или «gtk_threads_add_timeout()», то каков штатный способ чтобы отправить сообщение из GUI в рабочий поток? Потому как пересоздавать потоки под каждый чих это не по феншую, да и для ряда задач нужно последовательное выполнение команд в одном и том же потоке.
К GUI можно обращаться из нескольких потоков одновременно, достаточно обернуть код в gdk_threads_enter() / gdk_threads_leave(). Это позволяет избегать создания лишних функций для таймеров.
заверните код в тег (source lang=«ваш_язык») (/source)
вместо круглых скобок конечно же "<>". просто так парсер ест
&lt; и &gt; спасает:
<source lang="ваш_язык"> </source>
ничего не съедено ;)
И все-таки нафига всё это (именно в плане кросплатформенных потоков) с новым С++11?
Тут речь о Си. Без плюсов.
Интересно.
А каковы требования? Под ARM или freescale gnu-linux-gcc это скомпилирует? И код не придется переписывать под win64?
Если гтк поддерживает нужную платформу, то скомпилируется, кросс-платформ же
А gtk поддерживает win64?
Конечно, исходные коды ведь доступны, поэтому можно сделать порт на любую платформу.
Бинарники GTK+ для win64: ftp.acc.umu.se/pub/gnome/binaries/win64/gtk+
> Под ARM или freescale gnu-linux-gcc это скомпилирует?

Подозреваю, что намного проще в этом случае будет стандартными средствами воспользоваться (pthreads).
подозреваю, что я не случайно спросил про win вообще и про win64 в частности.
Нет, порт pthread под win существует, но даже в 32 битовой версии ошибок там есть столько, что это не вариант ;)
Так насчет win вопростов-то и не было!
Попытаюсь ответить на подобные вопросы:
А почему не Кьют?
Меня на самом деле волновал похожий вопрос но в более глобальном смысле, почему не C++?
А я бы спросил — почему не boost?

Целью статьи не было сравнение способов написания многопоточных кросс-платформанных приложений. Я предложил один из вариантов, который использую сам.
Несомненно, в Qt есть свои средства, и глупо было бы в Qt-шное приложение встраивать Glib, для С++ возможно больше подойдёт boost, но есть люди, которые предпочитают писать на чистом Си, такие как я, вот для них в первую очередь и предназначена эта статья.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории