Являются ли идентификаторы потоков и процессов уникальными? - PullRequest
5 голосов
/ 17 ноября 2009

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

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

Я думаю использовать идентификатор процесса, идентификатор потока и текущее время. Уникальна ли эта комбинация?

Платформа: Windows XP

Ответы [ 6 ]

10 голосов
/ 17 ноября 2009

Используйте базу данных для их генерации. Как это сделать, зависит от базы данных, но Postgres называет их последовательностями для примера.

5 голосов
/ 15 февраля 2011

В Windows идентификаторы потоков уникальны для всей системы. См. Эту статью библиотеки MSDN:

http://msdn.microsoft.com/en-us/library/ms686746%28v=VS.85%29.aspx

Функции CreateThread и CreateRemoteThread также возвращают идентификатор, который однозначно идентифицирует поток во всей системе. Поток может использовать функцию GetCurrentThreadId, чтобы получить свой собственный идентификатор потока. Идентификаторы действительны с момента создания потока до его завершения. Обратите внимание, что ни один идентификатор потока никогда не будет 0.

5 голосов
/ 17 ноября 2009

Идентификатор процесса / потока будет уникальным, если программы выполняются одновременно, поскольку ОС должна их различать. Но система повторно использует идентификаторы. Так что, для вашей ситуации, да, это хорошая идея добавить либо идентификатор процесса, либо идентификатор потока в ваш маркер, хотя я не думаю, что вам понадобятся оба.

3 голосов
/ 18 ноября 2009

К сожалению, комбинация идентификатора процесса, идентификатора потока и времени не гарантируется быть уникальной. ОС может повторно использовать идентификаторы процессов и идентификаторы потоков, как только потоки и процессы, на которые они ссылались, были прерваны. Также пользователь может установить часы назад, поэтому одно и то же время происходит дважды. Как уже говорили другие, я бы попросил базу данных для уникального идентификатора. В Oracle есть последовательности, в MySQL есть столбцы с автоинкрементом, в других базах данных аналогичные механизмы.

1 голос
/ 17 ноября 2009

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

Хотя, вероятно, маловероятно, что один из ваших процессов, запущенных на машине A, будет иметь тот же идентификатор процесса и идентификатор потока, что и один из ваших процессов, запущенных на машине B, это всегда те ошибки, которые в конечном итоге вынуждают людей встать с постели. в 4 часа ночи, чтобы справиться с звонком в службу поддержки ...

0 голосов
/ 17 ноября 2009

Что ж, добавление идентификатора процесса и идентификатора потока может привести к одному и тому же номеру

pid = 100, tid = 104 pid = 108, tid = 96

Не совсем вероятно, но возможно.

Так что для почти безопасных идентификаторов вам понадобится как минимум поле с 64-битным идентификатором, например

  ULONG64 id = ((ULONG64)(pid&0xffff) << 48) | ((ULONG64)(tid&0xffff) << 32) | (timestamp & 0xffffffff);

(однако, это все еще не гарантирует уникальность, так как предполагает, что идентификаторы потоков не пересекаются с идентификаторами процессов, что они нейтрализуют 16-битные значения, но я не думаю, что когда-либо видел PID более 65536 и если вы создаете тысячи потоков, идентификаторы потоков не будут переходить в это значение до перехода на отметку времени).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...