Показаны сообщения с ярлыком iphone. Показать все сообщения
Показаны сообщения с ярлыком iphone. Показать все сообщения

вторник, 22 января 2013 г.

Как прицеплять в Xcode-проект статические либы отдельно для Debug и Release

Это касается только Xcode 4 и более поздних версий:

ПЕРВЫЙ ТРУДОЁМКИЙ СПОСОБ: прицепить либы к дереву проекта намертво (вероятно можно и мышкой добавить нужные либы из Finder-папки перетаскивая их прямо в дерево проекта), но я делал это выходя в свойства проекта, потом переключался на вкладку Target, выбирал там Build Phases -> Link Binary With Libraries.

Этот первый способ плох тем, что Xcode порой глючит, и не в состоянии отличить дебаг-либу от релизной и может прицеплять дебаг-либу при релизной сборке приложения. Поэтому мне пришлось написать shell-скрипты, которые прятали в Temp-папки те либы, которые мне мешали и shell-скрипты для возвращения этих либ на прежние места. То есть перед Release-сборкой приложения все дебаг-либы можно аккуратно убрать одним запуском скрипта - при этом эти либы окрасятся в тревожный красный цвет в дереве проекта, но пусть это вас не пугает - приложение будет исправно собираться с оставшимися релизными либами.

НОВЫЙ ХОРОШИЙ СПОСОБ (пока плохо мной оттестирован): не добавлять либы первым способом в дерево проекта. Добавьте пути к нужным либам (включая имена файлов этих собранных либ) в настройках проекта и настройках таргета  -> Build Settings -> Linking -> Other Linker Flags (в подраздел Debug добавьте пути к дебаг-либам, в подраздел Release - к релиз-либам). Кроме того, вы можете в Debug/Release подразделы добавить вложенные подразделы для разных таргетов (для симуляторов и девайсов) - для этого найдите + кнопку справа внизу "Add Build Settings", нажмите на неё и выберите "Add Conditional Settings" (укажите пути для симуляторных и девайсовских дебаг/релиз либ).

суббота, 4 февраля 2012 г.

О важности IBOutlet прикрепления объектов к объекту-хозяину

Очень важно, если вы решили часть рутинных операций возложить на такой удобный инструмент как Interface Builder не забывать об одном правиле. Каждый объект, который создаётся не динамически в коде (например smthObject = [[SmthClass alloc] initWith... ]), а создан с помощью Interface Builder, каждый такой объект должен иметь своего хозяина (разве что главный делегат приложения гарантированно работает по умолчанию).

То есть любой ваш объект (созданный с помощью Interface Builder) должен принадлежать кому-нибудь как IBOutlet-переменная. Я убеждался в этом уже много раз на практике. Иначе происходят падения программы при попытке заставить этот объект что-либо сделать, из-за того, что у этого объекта (если он не принадлежит никому как IBOutlet-переменная) например вызывается метод, а объект вроде не существует (раз ни к кому не принадлежит). Может быть гуру-программисты дадут более точное объяснение этому явлению...

четверг, 15 декабря 2011 г.

О важности округления размеров GUI-контролов

Вчера мучался в догадках, почему под одной и той же ячейкой в UITableView (одна ячейка в одной группе, стиль выбран UITableViewStyleGrouped) появлялась одна и та же горизонтальная полосочка. Баг был явно привязан именно к этой ячейке.

Оказалось, что я задавал высоту ячейки не как целое или округлённое до целого число (то есть возвращал из метода heightForRowAtIndexPath значение с заметной на экране дробной частью).

четверг, 18 августа 2011 г.

Полезные ссылки для iOS-программиста

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

http://www.rsdn.ru/forum/apple.os/
http://touchdev.ru/
http://habrahabr.ru/blogs/macosxdev/

четверг, 17 марта 2011 г.

Стандартные размеры контролов

Материал взят из http://jdg.net/post/106465937/standard-iphone-element-sizes

Core Elements:

Carrier Status bar - 320x20
UIView - 320x460
UINavigationBar - 320x44
UITabBar - 320x49
UISearchBar - 320x44
UIToolBar - 320x44

Data Input:

UIPickerView - 320x216
UIDatePicker - 320x216
UIKeyboard - 320x216

Buttons:

UISegmentedControl - 320x44
UIButton xx37

Fields:

UITextField - xx37
UISwitch 94x27
UISlider - xx23

Indicators:

UIProgressView -xx9
UIActivityIndicatorView - 37x37
UIPageControl - 38x36

вторник, 14 сентября 2010 г.

Как вывести в отладочную консоль используемую память в iPhone-приложении

Материал взят из
http://stackoverflow.com/questions/2786539/iphone-memory-usuage

#import mach/mach.h

void report_memory(void) {
struct task_basic_info info;
mach_msg_type_number_t size
= sizeof(info);
kern_return_t kerr
= task_info(mach_task_self(),
TASK_BASIC_INFO
,
(task_info_t)&info,
&size);
if( kerr == KERN_SUCCESS ) {
NSLog(@"Memory used: %u", info.resident_size); //in bytes
} else {
NSLog(@"Error: %s", mach_error_string(kerr));
}
}

воскресенье, 4 июля 2010 г.

Высота стандартных iPhone-контролов по умолчанию

При разработке iPhone-приложений высота контролов по умолчанию:

Status Bar: 20px
Navigation Bar: 44px
Tab Bar: 50px

Если не ошибаюсь, аналогичная высота и у iPad-контролов.

Помнить эти значения приходится каждый раз, когда вы запихиваете в UIView всякие UITableView и прочие окошки.

Всё-таки Interface Builder при некоторых своих косяках даёт экономию времени (создавать контролы руками через код иногда бывает крайне необходимо, но это в любом случае приходится дольше делать, чем делать несколько движений мышкой в Interface Builder'e - ну и кроме того, снимается ряд головняков, например таких как контроль над утечками памяти программно создаваемых контролов). Особенно я люблю Interface Builder за возможность быстро создать взаимосвязи между контролами и функциями-обработчиками (где в качестве возвращаемого типа указываем IBAction).

Так вот - в ряде случаев применение Interface Builder'а позволяет значительно упростить задачу создавать в одном Xcode-проекте приложение сразу и для iPhone и для iPad (просто для разных экранов работаете мышкой с одноимёнными xib-файлами - поверьте, получается быстрее, чем вручную писать каждый раз if-else или #ifdef ТАКОЙ_ТО_ТИП_ДЕВАЙСА).

пятница, 11 июня 2010 г.

Макрос _T при переносе Win32 проектов на iPhone

Как правило сейчас уже во всех Win32 (MFC) проектах такая строка в коде _T("Я люблю вас, девочки") воспринимается компилятором как L"Я люблю вас, девочки" (то есть как wchar_t строка).

Чтобы не перелопачивать код, который вам нужно портировать из Windows в iPhone, можете добавить в общий заголовочный файл (например, в исходники, где определены все макросы и константы) такое макроопределение:

#ifdef __IPHONE_3_1
#ifndef _T
#define _T(a) L##a
#endif
#endif


После этого вам должно стать хорошо и приятно :)

среда, 2 июня 2010 г.

Проблемы с isnan функцией (при портировании кода Win32-приложения для iPhone)

Функции _isnan нет в iPhone OS (там должна быть функция isnan, включенная в math.h или cmath заголовки), поэтому я делаю такой трюк:

// где-то наверху файла
#ifdef __IPHONE_3_1
#include < cmath > // или #include < math.h >
#endif

// где-то в коде
#ifdef _WIN32
if(_isnan(val))
#elif defined(__IPHONE_3_1)
if (isnan(val))
#endif

//////////////////////////////////
// увы, иногда < cmath > или < math.h > бессильны нам помочь (мистика?),
// и тогда делайте так в одном месте, где-нибудь в общем заголовке:

#ifdef __IPHONE_3_1
#define _isnan(x) \
( sizeof (x) == sizeof(float ) ? __inline_isnanf((float)(x)) \
: sizeof (x) == sizeof(double) ? __inline_isnand((double)(x)) \
: __inline_isnan ((long double)(x)))
#endif //__IPHONE_3_1


Если вы хотите, чтобы #ifdef __IPHONE_3_1 условие точно срабатывало, то один из способов гарантировать это - сделать cpp файл типом objcpp (в свойствах файла, если щёлкнуть по имени файла в дереве Xcode-проекта). С заголовочными файлами обстоит немного посложнее, но если заголовочник уже включен в cpp-файл, с которым вы сделали как я советую, то обычно всё в порядке будет и в заголовочном файле.

среда, 26 мая 2010 г.

Разработка для iPhone на PHP и XML

Любопытный материал я обнаружил на http://www.ibm.com/developerworks/ru/library/x-iphonexmlphp

В сообществе фанатов Apple решили, что iPad нуждается в улучшениях

Материал взят из http://hitech.newsru.com/article/24may2010/ipadvsapplefans

В сообществе фанатов продукции Apple полагают, что весь потенциал планшетного компьютера iPad может быть раскрыт только с обновлением операционной системы iPhone OS, сообщает СОТОВИК.ру.

Многим пользователям, например, не хватает поддержки многозадачности наряду с улучшением управляемости.

Основной же проблемой называют слабость базы iPad-приложений: далеко не все готовы удовольствоваться двукратно масштабируемыми на 9,7-дюймовом экране приложениями для iPhone - ну разве что те, у кого зрение не столь остро.

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

Жесткая привязка к iTunes для загрузки приложений и цифрового контента несколько напрягает, хотя всегда есть альтернативные варианты "джейлбрейка", как называют взлом защиты в устройствах Apple.

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

воскресенье, 23 мая 2010 г.

Finger Piano Share: 10 пианистов в одном iPhone

Материал взят из http://www.ru-iphone.com/soft

Компания Yamaha совместно с двумя партнерами выпустит приложение для iPhone, которое позволит одновременно 10 пользователям играть на виртуальном пианино. Finger Piano Share, именно так называется этот продукт, разрабатывался под руководством японской компании Densan System. После запуска приложения на экране появятся виртуальные клавиши пианино, а размещенные подсказки будут направлять пользователей в игре на музыкальном инструменте.

Программа может быть подключена к MIDI-клавиатуре Yamaha через Интернет, то есть с помощью iPhone можно удаленно управлять MIDI-синтезатором. Работать с приложением могут одновременно до 10 человек, подчеркнул Ацуко Ито (Atsuko Ito), руководитель центра развития звуковых технологий в Yamaha (Yamaha Center for Advanced Sound Technologies).

Кроме того, Finger Piano Share совместимо с приложением Sekai Camera, разработанным токийской фирмой Tonchidot. Оно определяет местоположение устройства с помощью модуля GPS и предоставляет пользователю информацию, связанную с этой географической точкой во время просмотра через камеру.

среда, 19 мая 2010 г.

Сравнение строк вне зависимости от регистра символов

Данную функцию можно использовать для сравнения строк в C++ коде (главное, не забыть в дереве Xcode-проекта выставить тип C++ исходника как cpp.objcpp).

bool InsensitiveCompareStrings
(const char* left, const char* right)
{
NSString *leftTitle =
[NSString stringWithUTF8String:left];
NSString *rightTitle =
[NSString stringWithUTF8String:right];
return (NSOrderedAscending == [leftTitle
localizedCaseInsensitiveCompare:rightTitle]);
}


Функция хороша тем, что класс NSString в отличие от std::toupper позволяет отсортировать в правильном порядке даже символы русского алфавита (то есть маленькая русская а будет стоять раньше большой Я).

пятница, 14 мая 2010 г.

Перенос C++ шаблонов из Visual C++ в Xcode-проекты (для GCC-компилятора)

Коллеги подсказали на работе, почему GCC-компилятор (используемый в Xcode) иногда ругается на шаблоны, написанные для Visual C++.

В данном случае речь идёт о членах-данных шаблонных классов. Согласно стандарту языка, в телах членов-функций (методов) шаблонных классов перед именем члена нужно обязательно писать this-> (при этом это требование не является обязательным, если вы пишите C++ код в Visual Studio). GCC компилятор же упорно не замечает такие члены в телах функций шаблонных классов до тех пор, пока вы не напишите this-> (после этого всё успешно компилируется).

пятница, 30 апреля 2010 г.

Стив Джобс рассказал, почему Apple "не пускает" Flash на свои мобильные устройства

Материал взят из http://hitech.newsru.com/article/30apr2010/applewhynoflash

Глава Apple Стив Джобс разместил на официальном сайте компании открытое письмо Thoughts on Flash ("Размышления о Flash"). В нем он, как сообщает Ferra.ru постарался изложить свое видение причин, по которым Apple не разрешает и не разрешит использование технологии Flash на своих мобильных устройствах.

Flash, по мнению Джобса, не является открытой технологией. Хотя технология Flash широко распространена, она полностью контролируется Adobe и доступна лишь от этой компании. Таким образом, Flash фактически по любым меркам является закрытой проприетарной разработкой.

Аргумент Adobe о том, что благодаря отсутствию поддержки Flash пользователи iPhone и iPad лишаются полноценного доступа к веб-ресурсам, глава Apple называет устаревшим. Сайты YouTube, CBS, Netflix, Facebook и многие другие поддерживают работу с мобильными устройствами Apple.

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

Стив Джобс напоминает, что его специалисты в течение нескольких лет просили Adobe показать хорошо работающую технологию Flash на любом мобильном устройстве. Однако этого так и не случилось.

Что касается флеш-игр, Стив Джобс указывает, что им есть неплохая альтернатива в виде программ из App Store. Сейчас в этом онлайн-магазине присутствует более 50 000 игр и развлекательных приложений, причем, многие из них бесплатны.

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

Стив Джобс также отмечает, что технология Flash была разработана для ПК и компьютерной мыши, а не для сенсорных экранов, в то время как у Apple имеется фирменный multi-touch интерфейс, не требующий ничего, кроме пальцев.

Поэтому большинство сайтов с применением Flash все равно придется переписывать под устройства с сенсорным экраном. В Apple решили сразу делать это с применением современных технологий - например, HTML5, CSS и JavaScript.

Как получить пути к наиболее часто используемым папкам в iPhone-приложении

Вот как я обычно получаю все необходимые мне пути:

// 1. Путь к папке Documents:
NSString *nsDocsDir =
[NSHomeDirectory() stringByAppendingPathComponent:
@"Documents"];


// 2. Путь к кэш-папке (там хорошо что-либо временное сохранять, такое, что не жалко будет пользователю потерять):
NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
NSUserDomainMask, YES);
NSString *nsCachesDir = [paths objectAtIndex:0];

// 3. Путь к папке ресурсов:
NSString* resourcesDir = [[NSBundle mainBundle] resourcePath];

// И ещё пара полезных функций:
NSString* homeDir = NSHomeDirectory(); // вероятно, это корневая папка приложения
NSString* tempDir = NSTemporaryDirectory(); // возвращает полный путь к папке для временных файлов

Внимание: автор не претендует на полноту изложения! Смотрите документацию от Apple.

Чем заменить функцию stricmp в iPhone-проекте

Я пошарился в Гугле и нашёл интересный ответ на этот вопрос:

Смотрите документацию (введите man strcasecmp в командной строке - возможны какие-то различия в возвращаемых int-значениях).

Как выяснить причину EXC_BAD_ACCESS в Xcode

Нашёл интересную статью (на английском) на http://www.codza.com/how-to-debug-exc_bad_access-on-iphone (там это приводится с рисунками и комментариями читателей).

НАЧАЛО ЦИТАТЫ.

EXC_BAD_ACCESS. Debugging this one is on par with figuring out why the wife says “not tonight, honey.” And they are equally unfortunate situations.

Let’s see what we can do about EXC_BAD_ACCESS.

EXC_BAD_ACCESS happens when a message is sent to an object that has already been released. By the time the error is caught, the call stack is usually gone especially if dealing with multiple threads.

How nice would it be to keep a dummy around after the object is released that could stop execution, tell us what message was sent and show us the call stack… well, there’s a way to do just that.

If you set the NSZombieEnabled environment variable, the Objective C runtime will leave a dummy object behind for every deallocated object. When the zombie object is called, execution stops and you can see the message that was sent to the object and the call stack that tells you where the message came from (it doesn’t tell you where you over released the object, but knowing where the object is called from should get you pretty close to the problem.)

To set this variable, go to the info panel of the executable in xcode, and create a new environment variable in the arguments tab by clicking the plus sign in the lower left corner of the window. Name the variable NSZombieEnabled, type YES for the value and make sure that the checkbox is selected.
set NSZombieEnabled variable

set NSZombieEnabled variable

Go ahead and run your program now (in debug mode, because you need the stack information.) When the over released object is accessed, you get an error message similar to this (xcode debug view):

2009-03-30 02:30:36.172 ninjaJumper[3997:20b] *** -[GameLayer retain]: message sent
to deallocated instance 0x59bf670

This shows the class of the object (GameLayer) and the message sent (retain).

Let’s take a look at the stack now:
call stack

call stack

The methods printed in bold are in your code, the others are in some other API. Here you can see that the object was accessed from [Director touchesBegan:withEvent], where an array was copied (most likely the over released object was in the array.)

This information should get you pretty close to the problem.

Once the problem is fixed, make sure that the NSZombieEnabled variable is disabled. You don’t need to delete it, but make sure that the checkbox is unchecked:
NSZombie disabled

NSZombie disabled

Now about the wife. Good luck there. Try a box of chocolate or load the dishwasher for a couple days.

КОНЕЦ ЦИТАТЫ.

К СОЖАЛЕНИЮ, ДАННЫЙ СОВЕТ ПОЗВОЛЯЕТ ОТСЛЕЖИВАТЬ ИМЕНА Objective C КЛАССОВ. Я ТОЛЬКО ЧТО СДЕЛАЛ ТЕСТОВОЕ ПРИЛОЖЕНИЕ, В КОТОРОМ ПОЛЕЗНЫЕ ОТЛАДОЧНЫЕ СООБЩЕНИЯ ВЫВОДЯТСЯ В КОНСОЛЬ ТОЛЬКО КАСАЕМО Objective C КЛАССОВ:


TestClass *testObj = [[TestClass alloc] init];
[testObj release]; // уничтожили объект перед попыткой использования
[testObj printMsg];

В этом случае в консоль будет выводиться информация
2010-04-28 13:02:08.030 ZombieTest[1353:207] *** -[TestClass printMsg]: message sent to deallocated instance 0x3924880)


В случае же с C++ классом:

TestCppClass *tcpp = new TestCppClass();
delete tcpp;
tcpp = 0;
tcpp- >PrintMsg(); // удивительно, но это работает (на экран выводится тестовое сообщение, так как вероятно функция-член класса способна работать и без создания объекта - ЭТО ЧТО, ОЧЕРЕДНОЙ БАГ Xcode?)
delete tcpp; // тем не менее здесь код спотыкается, так как пытаемся уничтожить объект повторно

в консоль выводится то же самое что и без применения совета из приведённой статьи):
2010-04-28 13:04:45.242 ZombieTest[1476:207] TestClass --- printMsg
ZombieTest(1476,0xa0a7b4e0) malloc: *** error for object 0x3917160: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

вторник, 27 апреля 2010 г.

Как сделать скрипт для компиляции и линковки сразу нескольких Xcode-проектов

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

В Мac OS в командной строке (в терминале) всё делается примерно также, как и в любой Unix-подобной системе.

Чтобы оставаться в терминале, можно даже и не открывать текстовый отдельный редактор, потому что есть встроенные редактор vi (или vim, насколько я знаю, этот редактор очень любят старые Linux-хакеры). Справку по этому редактору можно найти во многих статьях и учебниках (посвящённых Unix/Linux).

В самом верху вашего скрипта (текстового файла, содержащего все необходимые команды для выполнения) введите:

#!/bin/bash

Для того, чтобы добавить в скрипт команду для сборки (компиляции и линковки) Xcode-проекта, добавьте строку (вместо myProject.xcodeproj нужно указать правильный путь к файлу проекта):

xcodebuild -project myProject.xcodeproj -target targetname

(насчёт аргумента, который нужно ввести вместо targetname можно выяснять набрав команду
man xcodebuild

Можно заранее сделать все настройки, открыв проект в среде разработки Xcode (и поставив все необходимые опции, используя графический интерфейс). А потом уже написать в скрипте:

xcodebuild -project myProject.xcodeproj -activetarget

При выполнении этой команды всё будет компилироваться и линковаться точно также, как если бы вы снова открыли ваш проект в среде разработки и нажали на кнопочку "Build".


После того, как напишите и сохраните ваш скрипт (из команд для сборки нескольких проектов), обязательно позвольте ему стать исполняемым файлом, выполнив в терминале команду (при условии, что вместо scriptFileName указан правильный путь к файлу):

chmod +x scriptFileName

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

Ну вот собственно и всё.

Какой аналог у SetEvent (Win32) в pthread?

Материал взят из http://electronix.ru:1288/forum/lofiversion/index.php/t47683.html

Andrey Sudnov
May 13 2008, 11:36
Проблема в том, что в библиотеке PThread нет работы с файловыми дескрипторами. Соответственно, для того чтобы одновременно ожидать завершения какой-либо файловой (или сокетовой) операции или поступления управляющего сигнала от другого потока (например, об отмене операции), приходится использовать неименнованные каналы (pipe и write, вместо SetEvent) и функцию poll (предпочитаю ее, а не select). Перерыл кучу книг, в том числе POSIX стандарт, ничего лучше не придумал. Насколько такое решение накладно по ресурсам? Как организовать такое взаимодействие потоков другим способом?
KRS
May 14 2008, 11:38
в POSIX есть mutex и Condition Variables
я когда игрался с POSIX под сигвин делал примерно так:

typedef struct {
pthread_mutex_t lock;
pthread_cond_t event;
bool flag;
}event_t;

static inline void event_init(event_t* event)
{
pthread_mutex_init(&event- >lock,0);
pthread_cond_init(&event- >event,0);
event- >flag=false;
}

static inline void event_set(event_t* event)
{
pthread_mutex_lock(&event- >lock);
if (!event- >flag) {
event- >flag=true;
pthread_cond_signal(&event- >event);
}
pthread_mutex_unlock(&event- >lock);
}

static inline bool event_wait(event_t* event, unsigned s_timeout)
{
bool r;
pthread_mutex_lock(&event- >lock);
if(!event- >flag) {
if (s_timeout) {
timespec_t timer;
clock_gettime(CLOCK_REALTIME,&timer);
timer.tv_sec+=s_timeout;
pthread_cond_timedwait(&event- >event,&event- >lock,&timer);
}else {
do {
pthread_cond_wait(&event- >event,&event- >lock);
}while(!event- >flag);
}
}
r=event- >flag;
event- >flag=false;
pthread_mutex_unlock(&event- >lock);
return r;
}
RCray
May 15 2008, 12:05
да. это даже лучше, чем poll, который не для всех устройств реализован. к тому же в вашем коде подчерпнул кое-что для себя, спасибо.
RCray
May 15 2008, 13:23
только у меня так:


void* child_func(void* arg)
{
struct args_t* args = (args*)arg;

args- >size = read(args- >fd, args- >packet, args- >supposed_size);
args- >event.flag = 1;
pthread_cond_signal(&args- >event.event);

return 0;
}

int parent(struct args_t *args)
{
pthread_t child;
struct timespec tm;

if ( pthread_create(&child, NULL, child_func, args) != 0 )
return ERR_CREATE;

// задание таймаута
...

while(!args- >event.flag)
{
res = pthread_cond_timedwait(&args- >event.event, &args- >event.lock, &tm);
if (res == ETIMEDOUT)
return ERR_TIMEOUT;
}

args- >event.flag = 0;
return args- >errors;
}

KRS
May 15 2008, 15:31
Без mutex есть потенциальные проблемы:
если между проверкой и очисткой возникнет еще одно событие вы его потеряете потому что обнулите args- >event.flag = 0;

(2b|!2b?.. @ May 15 2008, 14:08) [snapback]411551[/snapback]


while(!args- >event.flag)
{
res = pthread_cond_timedwait(&args- >event.event, &args- >event.lock, &tm);
if (res == ETIMEDOUT)
return ERR_TIMEOUT;
}

args- >event.flag = 0;
return args- >errors;
}



RCray
May 15 2008, 15:59
(KRS @ May 15 2008, 16:16) [snapback]411655[/snapback]

Без mutex есть потенциальные проблемы:
если между проверкой и очисткой возникнет еще одно событие вы его потеряете потому что обнулите args- >event.flag = 0;


да, опять вы правы.
к тому же не лишним будет это

res = pthread_cond_timedwait(&args- >event.event, &args- >event.lock, &tm);
if (res == ETIMEDOUT)
{
pthread_cancel(созданный ранее поток, от которого ожидается сигнал);
return ERR_TIMEOUT;
}

Andrey Sudnov
May 18 2008, 07:14
Не нахожу ответа на свой вопрос... Уточняю условие.
Можно использовать poll, можно select, разницы нет, дело вкуса. Проблема в том, что БЕЗ этих функций невозможно отследить окончание операции с файлом (read, write, recv, send, conect, etc...).
Ситуация следующая. Есть два потока. Один - интерфейс, и там есть кнопка Exit. Другой - работа с сокетами. Работа с сокетами должна быть немедленно прекращена, как только нажали кнопку Exit. Для этого необходимо ждать одновременно и файловый дескриптор (poll/select) и event от pthread (если мы работаем через них). Это невозможно - нет такой функции. В Windows есть такой тип: HANDLE. Он общий и для событий (SetEvent) и для дескрипторов ввода/вывода. Соответственно, оба можно одновременно передать в функцию WaitForMultipleObjects.
Вижу два варианта. Первый: вызывать poll/select с установленным таймаутом в несколько миллисекунд, затем проверять событие и так по кругу. С кнопкой это конечно прокатит, но в случае жесткого реального времени задержка на обработку события будет составлять именно этот таймаут. К тому же постоянное верчение в юзеровском коде не делает чести с точки зрения использования ресурсов и производительности.
Второй вариант: отказаться от синхронизирующих функций pthread нафиг. Использовать pipe. Здесь встает вопрос, насколько эффективно реализованы эти каналы в коде ОС/libc. И не перекрывает ли потенциальная кривая реализация преимуществ над первым вариантом?
Варианты еще?
vshemm
May 18 2008, 17:31
(Andrey Sudnov @ May 18 2008, 07:59) [snapback]412873[/snapback]

Второй вариант: отказаться от синхронизирующих функций pthread нафиг. Использовать pipe. Здесь встает вопрос, насколько эффективно реализованы эти каналы в коде ОС/libc. И не перекрывает ли потенциальная кривая реализация преимуществ над первым вариантом?

А ОС, собственно, какая?
Впрочем, если не нравятся пайпы, можно использовать сокеты smile.gif Для них есть высокоэффективная реализация оповещения об изменении состояния, правда, механизмы в разных ОС разные. Гляньте сюда - http://monkey.org/~provos/libevent/
Так или иначе, задержки будут намного меньше таймаута в неск. миллисекунд при небольшом количестве сокетов.

Варианты еще?

Сигналы?

А вот что пишет Steven Grimm (http://monkeymail.org/archives/libevent-users/2007-January/000450.html):

no UNIX-ish system I'm aware of has an equivalent to the Windows
WaitForMultipleObjects API that allows you to wake up on semaphores /
condition variables and on input from the network. Without that, any
solution is going to end up using pipes (or maybe signals, which have
their own set of issues in a multithreaded context) to wake up the
libevent threads.

однако, про локальные сокеты он почему-то не упоминает.

И еще smile.gif Вы зря,имхо, предпочитаете poll select'у, т.к. poll при каждом вызове гоняет структу в ядро = > большой оверхед. С другой стороны селект имеет ограничени на кол-во дескрипторов. Во всяком случае в linux это так, поэтому и появился epoll().

Постоянные читатели