Аннотация:
В статье описаны некоторые детали программирования служб Windows NT/2000/XP. Большая часть содержащихся в статье утверждений описывает реакцию Windows на какие-то действия службы. Если вы написали первую службу и хотите двигаться дальше, эта статья вам поможет.
Здравствуйте, Сергей Холодилов, Вы писали:
СХ>Статья: СХ>Программирование служб: подробности
СХ>Авторы: СХ> Сергей Холодилов
СХ>Аннотация: СХ>В статье описаны некоторые детали программирования служб Windows NT/2000/XP. Большая часть содержащихся в статье утверждений описывает реакцию Windows на какие-то действия службы. Если вы написали первую службу и хотите двигаться дальше, эта статья вам поможет.
И зачем было писать в статье вот такой бред:
"На первый взгляд задействовано три потока: один исполняет main/WinMain, второй – ServiceMain, третий – Handler[Ex] (не совсем так, см. «Мелочи»). Очевидно, что первый и третий потоки не подходят."
Кто тебе это сказал про HandlerEx, или ты свои догадки помещаешь сюда? Какой отдельный поток для HandlerEx? У тебя на один поток больше указано.
Здравствуйте, SLI, Вы писали:
SLI>И зачем было писать в статье вот такой бред: SLI>"На первый взгляд задействовано три потока: один исполняет main/WinMain, второй – ServiceMain, третий – Handler[Ex] (не совсем так, см. «Мелочи»). Очевидно, что первый и третий потоки не подходят."
SLI>Кто тебе это сказал про HandlerEx, или ты свои догадки помещаешь сюда? Какой отдельный поток для HandlerEx? У тебя на один поток больше указано.
Учись читать. Написано же ясно: "На первый взгляд... (не совсем так, см. «Мелочи»)". Я вкурсе, что Handler[Ex] и main/WinMain это один поток, это не мои догадки, я проверял с помощью GetCurrentThreadId(). Но я не считаю этот факт скольконибудь важным, поэтому упомянул его только в разделе Мелочи. На который и ссылаюсь.
Здравствуйте, SergH, Вы писали:
SH>Здравствуйте, SLI, Вы писали:
SLI>>И зачем было писать в статье вот такой бред: SLI>>"На первый взгляд задействовано три потока: один исполняет main/WinMain, второй – ServiceMain, третий – Handler[Ex] (не совсем так, см. «Мелочи»). Очевидно, что первый и третий потоки не подходят."
SLI>>Кто тебе это сказал про HandlerEx, или ты свои догадки помещаешь сюда? Какой отдельный поток для HandlerEx? У тебя на один поток больше указано.
SH>Учись читать. Написано же ясно: "На первый взгляд... (не совсем так, см. «Мелочи»)". Я вкурсе, что Handler[Ex] и main/WinMain это один поток, это не мои догадки, я проверял с помощью GetCurrentThreadId(). Но я не считаю этот факт скольконибудь важным, поэтому упомянул его только в разделе Мелочи. На который и ссылаюсь.
Учись писать- это тупая догадка ни на чем не основана, это ощущение лишнего потока возникло у тебя лично и к другим не относится. Потока-то нет. Разберись с тем что такое поток!
Re[3]: Программирование служб: подробности
От:
Аноним
Дата:
03.07.03 10:30
Оценка:
Здравствуйте, SergH, Вы писали:
SH>Здравствуйте, SLI, Вы писали:
SLI>>И зачем было писать в статье вот такой бред: SLI>>"На первый взгляд задействовано три потока: один исполняет main/WinMain, второй – ServiceMain, третий – Handler[Ex] (не совсем так, см. «Мелочи»). Очевидно, что первый и третий потоки не подходят."
SLI>>Кто тебе это сказал про HandlerEx, или ты свои догадки помещаешь сюда? Какой отдельный поток для HandlerEx? У тебя на один поток больше указано.
SH>Учись читать. Написано же ясно: "На первый взгляд... (не совсем так, см. «Мелочи»)". Я вкурсе, что Handler[Ex] и main/WinMain это один поток, это не мои догадки, я проверял с помощью GetCurrentThreadId(). Но я не считаю этот факт скольконибудь важным, поэтому упомянул его только в разделе Мелочи. На который и ссылаюсь.
Вот ты советуешь научиться читать, а сам то не очень это умеешь. Про то где исполняется HandlerEx разжовано у Рихтера с Кларком. Ты пишешь что прочитал их, и тут же выдаешь такой ляп про "кажется". А еще и проверять умудряешься с помощью получения TID. Тяжелый случай.
Здравствуйте, Аноним, Вы писали:
А>Вот ты советуешь научиться читать, ...
Нахамил напрасно. Ивиняюсь перед всеми собравшимися.
А>Про то где исполняется HandlerEx разжовано у Рихтера с Кларком. Ты пишешь что прочитал их, и тут же выдаешь такой ляп про "кажется". А еще и проверять умудряешься с помощью получения TID. Тяжелый случай.
1. Мало ли у кого что написано. Проверить никогда не мешает. Предложи другой метод проверки.
2. Нормальному человеку, который не читал Рихтера, Кларка, MSDN и прочее в голову не придёт предположить, что Handle[Ex] и WinMain выполняются одним потоком. Это и называется на первый взгляд.
3. То, что это один поток практически не влияет на програмирование служб. Поэтому я почти не уделяю этому факту внимание. Если ты считешь, что влияет, укажи как.
Учусь.
А>это тупая догадка ни на чем не основана, это ощущение лишнего потока возникло у тебя лично и к другим не относится.
У тебя не возникло? Верю. Только за всех не надо.
А>Потока-то нет.
Вот ведь блин! Оказывается и нет! Чувствовал же, что-то там не так...
А>Разберись с тем что такое поток!
Напиши статью на эту тему. Буду рад, если почерпну что-нибудь новое. Ссылки на нечитанные мною материалы по этому поводу также приветствуюся. Рихтера, Соломона с Руссиновичем и MSDN я вроде читал, ссылки на них не предлагать.
Какой умный мальчик — и Соломона с Руссиновичем он прочитал даже. Дак вот только :"Смотрю в книгу- вижу..." А рекомендовать не буду. Ты любишь учить- ну и учи.
У меня кстати не возникло подозрения про лишний поток. Так что это только у тебя.
Re[5]: Программирование служб: подробности
От:
Аноним
Дата:
04.07.03 13:28
Оценка:
Здравствуйте, SergH, Вы писали:
Меня что возмутило- ты приводишь свою догадку, а опровергаешь ее в конце статьи. Нафиг так делать?
Слова "не совсем так" означают небольшое расхождение- а тут разница в том есть поток или нет- это принципиально!
Это меня очень разозлило. И как только редакторы эту строчку пропустили.
Здравствуйте, Аноним, Вы писали:
А>Меня что возмутило- ты приводишь свою догадку, а опровергаешь ее в конце статьи.
Это — не моя догадка. Мне догадываться не надо. Я знаю, что там потока два, а не три, я читал об этом и сам проверял.
Я нигде не говорю, что это правда. Я говорю: "На первый взгляд .. " и тут же уочняю, что это первый взгляд несколько ошибочен. Я сомневаюсь, что всем с первого взгляда очевидно, где какой поток. Так как не вижу никаких серьёзных предпосылок к использованию именно такой архитектуры. Возможно так немного удобнее разработчикам ОС. Но разве это аргумент для Microsoft?
А>Нафиг так делать?
Чтобы не перегружать читателя бесполезными подробностями, отвлекающими от общей мысли раздела.
А>Слова "не совсем так" означают небольшое расхождение- а тут разница в том есть поток или нет- это принципиально!
В отличии от тебя я считаю это не принципиальным. Потому как могли сделать так, а могли иначе, а могут поменять. Повторюсь — глубоких причин, по которым лишний поток не создаётся я не вижу. Ну, окромя оптимизации ресурсов, но она не очень-то глубокая. А как всё это влияет на программиста я вообще не понимаю. Мне, как разработчику службы, плевать на то в одном потоке выполняется Hannler и main или в разных. Если вдруг начнут создавать отдельный поток, я, скорее всего, ни строчки не поменяю.
А>Это меня очень разозлило.
А зря.
А>И как только редакторы эту строчку пропустили.
Здравствуйте, Сергей Холодилов, Вы писали:
СХ>Статья:
СХ>Авторы: СХ> Сергей Холодилов
СХ>Аннотация: СХ>В статье описаны некоторые детали программирования служб Windows NT/2000/XP. Большая часть содержащихся в статье утверждений описывает реакцию Windows на какие-то действия службы. Если вы написали первую службу и хотите двигаться дальше, эта статья вам поможет.
Прошу прощения, я взял ваш код и попытался его скомпилировать, но VC упорно не хочет его линковать и выдаёт ошибку линкера в стиле "не найдена функция WinMain". В чём может быть проблема?
Здравствуйте, Bob Kotl, Вы писали:
BK>Прошу прощения, я взял ваш код и попытался его скомпилировать, но VC упорно не хочет его линковать и выдаёт ошибку линкера в стиле "не найдена функция WinMain". В чём может быть проблема?
Наверное в том, что пример — консольное приложение, в нем действительно нет WinMain.
Здравствуйте, SergH, Вы писали:
SH>Здравствуйте, Bob Kotl, Вы писали:
BK>>Прошу прощения, я взял ваш код и попытался его скомпилировать, но VC упорно не хочет его линковать и выдаёт ошибку линкера в стиле "не найдена функция WinMain". В чём может быть проблема?
SH>Наверное в том, что пример — консольное приложение, в нем действительно нет WinMain.
так я меняю define _WINDOWS на _CONSOLE, и всё равно не хочет... почему?
Здравствуйте, Bob Kotl, Вы писали:
BK>так я меняю define _WINDOWS на _CONSOLE, и всё равно не хочет... почему?
В примере проект полностью, т.е с dsp и dsw-файлами. Попробуй его так и собирать. Только что взял код с сайта, проверил проекты Serv и serv_tiny, компилится и собирается без проблем. Среда — VC6 SP5
Здравствуйте, SergH, Вы писали:
SH>Здравствуйте, Bob Kotl, Вы писали:
BK>>так я меняю define _WINDOWS на _CONSOLE, и всё равно не хочет... почему?
SH>В примере проект полностью, т.е с dsp и dsw-файлами. Попробуй его так и собирать. Только что взял код с сайта, проверил проекты Serv и serv_tiny, компилится и собирается без проблем. Среда — VC6 SP5
пардон, недосмотрел кое-что в установках проекта. В опциях линкера почему-то стояло /subsystem:windows. Поставил /subsystem:console — помогло.
Sorry
Re[5]: Программирование служб: подробности
От:
Аноним
Дата:
26.05.04 07:52
Оценка:
безполезная трата времени, трафика и нервов.
Все это, имхо, не принципиально... даже интереснее читать мысли человека, который пытается разобратся, чем уже пережеваный текст.
Мне интересен следующий вопрос.
MS рекомендует работать в ServiceMain. Поток для него создает SCM с помощью CreateThread (это предположение — потому как других вариантов нет).
В MSDN'не же не рекомендуется пользоватся CreateThread. Вместо этого нужно пользоваться родными ф-ми создания потока (_beginthread напр). Почему? Объяснять наверное не надо.
как быть? у меня 2 варианта
1. Создавать в ServiceMain новый поток и возвращать управление
2. завершать ServiceMain _endthread
Здравствуйте, Аноним, Вы писали:
А>безполезная трата времени, трафика и нервов.
Нервы то зачем? Не надо их тратить на дурацкие статьи, не стоят они того.. И не не дурацкие не надо, всё равно не стоят..
А>Мне интересен следующий вопрос. А>MS рекомендует работать в ServiceMain. Поток для него создает SCM с помощью CreateThread (это предположение — потому как других вариантов нет). А>В MSDN'не же не рекомендуется пользоватся CreateThread. Вместо этого нужно пользоваться родными ф-ми создания потока (_beginthread напр). Почему? Объяснять наверное не надо.
Я только одну причину знаю — инициализируется библиотека C. И деинициализируется при завершениии потока. Если имеется ввиду что-то иное, объясни.
А>как быть? у меня 2 варианта А>1. Создавать в ServiceMain новый поток и возвращать управление А>2. завершать ServiceMain _endthread
3. Я бы забил на диенициализацию. Смерть процесса всё очистит. А инициализация произойдёт при первом обращении к функциям, которые в ней нуждаются. Во всяком случае, так написано у Рихтера и практика, вроде подтверждает. Исходники CRT на эту тему, правда, не смотрел.
А>какие варианты будут у Вас?
Извини, я привык на ты. Предлагаю и тебе, хотя бы в общении со мной.
Здравствуйте, SergH, Вы писали:
SH>Я только одну причину знаю — инициализируется библиотека C. И деинициализируется при завершениии потока. Если имеется ввиду что-то иное, объясни.
это и имел ввиду. для каждого потока создается структурка THREAD_INFO. удаляется в _endthread.
А>>как быть? у меня 2 варианта А>>1. Создавать в ServiceMain новый поток и возвращать управление А>>2. завершать ServiceMain _endthread SH>3. Я бы забил на диенициализацию. Смерть процесса всё очистит.
typedef struct _thread_data
{
struct _thread_data *thread_link; /* next struct on free list */void *thread_arglist; /* argument list to pass to thread_func */
HANDLE thread_handle; /* handle of thread object */int thread_errno; /* errno */int thread_doserrno; /* _doserrno */void (_USERENTRY *thread_func)(void *); /* thread starting address */char *thread_token; /* pointer to next strtok() token */char *thread_template; /* pointer to temp filename template */int thread_mbshift; /* shift state for mbtowc() */int thread_wcshift; /* shift state for wctomb() */void (_USERENTRY **thread_sig)();/* pointer to signal table */void *thread_excep; /* exception registration pointer */void *thread_time; /* data used by time functions */void *thread_cvt; /* array used by fcvt() and ecvt() */void *thread_strbuf; /* array used by strerror() */void *thread_passbuf; /* array used by getpass() */void *thread_pathbuf; /* array used by searchpath() */
__seed_t thread_seed; /* random number seed */void *thread_exceptvars;
#if defined(_MBCS)
int thread_lead_byte; /* pending leadbyte data used by putch() */#endif
int thread_ex_mode; /* 1 means _beginthreadex was called */int thread_xtra; /* extra place holder. unused for now */
} THREAD_DATA;
структурка маленькая — ~80 байт. просто я не люблю такой подход.
SH>А инициализация произойдёт при первом обращении к функциям, которые в ней нуждаются. Во всяком случае, так написано у Рихтера и практика, вроде подтверждает. Исходники CRT на эту тему, правда, не смотрел.
исходники тоже
SH>Извини, я привык на ты. Предлагаю и тебе, хотя бы в общении со мной.
ок.
я тут подумал, _endthread тоже некорректно. По прототипу ServiceMain не подходит для создания потока, Значит ее кто-то вызывает и по возвращению из нее может что-то делать.
Почему MS не дала возможность создавать поток нам?
PS у меня тот же вопрос к ф-ии BeginThread в BCB. Она не совместима с _beginthread.
вобщем выход — не юзать RTL.