Мой софт написан на C ++ и вызывается скриптами Python (через Swig).
Когда в скриптах вызывается функция python uuid.uuid1 (), семя, используемое std :: rand () из C ++, кажется потерянным. Это проблема, потому что я должен иметь возможность перезапустить мой софт с точно таким же поведением в коде C ++ (это не имеет значения для uniqid).
Проблема упрощается в следующем примере:
C ++ файл testrand.h:
#ifndef __INCLUDE__TESTRAND_H__
#define __INCLUDE__TESTRAND_H__
void initialize(unsigned long int seed);
unsigned long int get_number();
#endif
C ++ файл testrand.cpp:
#include "testrand.h"#include <cstdlib>
void initialize(unsigned long int seed)
{
std::srand(seed);
}
unsigned long int get_number()
{
return std::rand();
}
Swig файл testrand.i:
%module testrand
%{
#include "testrand.h"%}
%include "testrand.h"
Компиляция выполняется с помощью следующей команды:
swig -python -c++ testrand.i
g++ -c -fPIC testrand.cpp testrand_wrap.cxx -I/usr/include/python2.7/
g++ -shared testrand.o testrand_wrap.o -o _testrand.so
Если я запускаю следующий тестовый пример python несколько раз, я вижу, что первое число всегда одинаково (как и ожидалось), но второе число, генерируемое после вызова uuid.uuid1 (), изменяется при каждом запуске.
import testrand
import uuid
testrand.initialize(10)
x1 = testrand.get_number()
print x1
uuid.uuid1()
x2 = testrand.get_number()
print x2
Несколько прогонов:
> python testcase.py
1215069295
1691632206
> python testcase.py
1215069295
746144017
> python testcase.py
1215069295
377602282
Вы знаете, как я могу использовать Python UUID, не убивая мой C ++ семян?
Заранее спасибо. (РЕДАКТИРОВАТЬ: моя конфигурация: Linux openSUSE 12.3, 64 бита, python 2.7.3 (но та же проблема с 2.7.2), swig 2.0.9, gcc 4.7.2 (но та же проблема с 4.5.1))
Я нашел код uuid здесь: http://pythoninside.com/en/source-code/2.7.5/uuid/uuid.py а также
Я скопировал и использовал код в примере сценария (т.е. без импорта uuid). Проблема исходит от звонка _uuid_generate_time(_buffer)
в строке 500. Эта функция определяется как псевдоним ctypes.CDLL(ctypes.util.find_library('uuid')).uuid_generate_time
в строках 402-410.
Это единственное упоминание об ошибке, которую я нашел: https://savannah.cern.ch/bugs/?24456
Возможно, вам нужно использовать uuid.uuid4()
в вашем коде Python.
uuid1()
генерируется из идентификатора хоста, порядкового номера и текущего времени, где как uuid4()
генерируется случайным образом.
(Хотя вопрос все еще остается: если uuid1()
действительно использует текущее время, то как же он может производить тот же uuid, как показано здесь в каждом из первых запусков.)
Я нашел решение, чтобы обойти проблему.
На самом деле, семя C ++ инициализируется модулем uuid только один раз (при первом вызове функции uuid.uuid1()
). Если я изменю свой пример сценария, добавив бесполезный первый вызов функции, у меня не будет проблемы:
import testrand
import uuid
uuid.uuid1()
testrand.initialize(10)
x1 = testrand.get_number()
print x1
uuid.uuid1()
x2 = testrand.get_number()
print x2