2013-06-24 2 views
3

У меня есть таблица, из которой я выбираю конкретные записи и обновляю их. Теперь я хочу запустить две отдельные программы для выполнения этой задачи.
Стол submission, который хранит программу Доводы в contest.It имеет атрибут status, который первоначально Queued и позже изменено на Wrong Answer, Accepted etc.so моя программа читает те записи, которые имеют статус Queued и оценивает их.

Теперь, если я запустил эту программу на двух отдельных терминалах, скажите program_1 and program_2. Если program_1 читает запись с Queued, то я не хочу program_2, чтобы прочитать ее, потому что это будет означать переоценку представления. Это побеждает мою цель параллельной оценки. Также если я поместил блокировку записи, прочитанной program_1, решит проблему. Но тогда program_2, возможно, придется дождаться освобождения блокировки, даже когда program_1 оценивает представление и после его освобождения блокировка program_2 не имеет ничего общего с этим представлением, поскольку его статус будет чем-то другим от Queued as он уже был бы оценен program_1. Это снова проиграет цель параллельной оценки.
Как мне обойти эту проблему ??Как читать только те записи, у которых нет блокировки на них?

+1

Можете ли вы попытаться разделить свои строки на равные части 'nbPerProg = (nb_rows/nb_prog)'? сохраните смещение и используйте предложение LIMIT как 'LIMIT offset, nbPerProg'. Каждая программа будет иметь свою часть своей таблицы для проверки. – Marcassin

+0

@Marcassin Я подумал о чем-то подобном, но как обрабатывать случай, когда одна программа внезапно останавливается, все решения одного конкретного вида не будут оцениваться? –

+1

В этом случае около 2 решений: 1) зависит от вашего языка программы, но если вы можете обрабатывать исключение, ловить ошибку во время обработки в строке и сохранять текущий идентификатор или текущее смещение и повторно запускать программу с помощью LIMIT (смещение + currOffset), (nbPerProg - currOffset), чтобы завершить необработанные строки. 2) Для каждой обрабатываемой строки обновите столбец DATETIME с текущим временем или номером вашей обработки или ..., чтобы узнать, какие из них были обработаны во время последних запусков ваших программ. – Marcassin

ответ

1

Если вы заинтересованы только в растворе ровно две программы, как о вас просто отсортировать таблицу первичного ключа, и имеют program_1 начало от верхней части списка и program_2 оттолкнуться от дна? Это ограничивает ваше дублирование усилий не более чем одной записью (той, где усилия двух программ «встречаются посередине»). И если одна программа умирает только после нескольких записей, другая сможет закончить работу.

(Конечно, если одна программа умирает после того, как только несколько записей, есть вероятность, что есть достаточно серьезна ошибка, что другая программа скоро умрет тоже.)

FWIW, я рекомендую не пытаться сделать это в все. Наличие двух процессов в борьбе с недифференцированной рабочей нагрузкой никогда не является хорошей идеей. Если вы хотите ускорить обработку, выполните запрос в одном потоке, а затем явным образом разделите работу между несколькими другими потоками. (Вы можете сделать то же подход, порождения новых процессов, а не порождая новые темы, или даже делая RPC, других физических машин;. Но действительно кажется излишним для меня)

Т.е., вместо

L = result_of_SQL_query(); 
worker1.process(L) & worker2.process(L); 

вы должны делать

L = result_of_SQL_query(); 
L1 = first_half_of(L); 
L2 = second_half_of(L); 
worker1.process(L1) & worker2.process(L2); 

Если вы беспокоитесь, что worker1 может умереть, то вам нужен способ для родительского процесса, чтобы обнаружить, что ребенок умер, запрос для оставшейся workl oad, а затем перераспределить эту нагрузку на другого ребенка.

+0

спасибо за такое подробное объяснение действительно полезные приветствия !!! –