Интересны атомарные операции, optimistic locks, неблочащиеся структуры данных, транзакционность в многопоточном окружении, применение этого всего на практике(без привязки к какому-то API). Мьютексы/семафоры/баяны не интересны. Буржуйским владею.
первая на вскидку http://www.ebook-4download.com/2010/10/multithreading-applications-in-win32/ если кому надо - cd к книге нашлось 8мег http://www.informit.com/title/0201442345 http://www.informit.com/content/images/0201442345/CDContents/CDcontents.zip
featurelles Просмотрел. В твоей про атомарные операции ровно 2 страницы текста + описание API + пара примеров... В соответствующем разделе, "атомарные операции". К сожалению, этого мне недостаточно.
scf У меня вопрос. "неблочащиеся структуры данных, транзакционность в многопоточном окружении" Здесь нет противоречия?
Вообще нет. Используя версионность данных, создание копий и "правильный" порядок обновления элементов данных, можно добиться транзакционности. Как при этом резолвить конфликты - это, конечно, уже отдельный вопрос Применения: -sql server snapshot isolation -облачные/кластерные базы - master-to-master replication -практическое применение документ-ориентированных СУБД. Они предоставляют по сути то же API, что и атомарные операции - get-and-set и т.п. Мне не особо хочется изобретать велосипеды, вот и интересуюсь, может их кто-то изобрел до меня... edit: еще забавная штука - структуры данных на атомарных операциях - очереди, стеки, может даже ассоциативные массивы... Они используют оптимистичную блокировку и поэтому куда шустрее классических реализаций на мьютексах. Вот только инфу о принципах построения таких вещей фиг найдешь.
scf Хороших книг не видел. А вы уверены что оптимистическая блокировка связана с атомарными операциями? Там не сложно. Только я пришёл к выводу что при параллельном программировании используются другие структуры и механизмы и их больше чем классических. Классические хотя и лежат в основе, но как по мне это уже новые структуры.
Гуг сразу выдал про неблокирующие структуры стек,очередь и тд. http://www.ibm.com/developerworks/ru/library/j-jtp04186/index.html
Pavia Ну как Я всегда считал, что оптимистичная(или оптимистическая? optimistic lock короче) блокировка - это когда сначала разделяемый ресурс захватывается, а уже потом определяется, был ли конфликт при захвате. Если конфликт был - то операция повторяется позже. И я в курсе всего о двух механизмах синхронизации - блокирующий(мьютексы и производные от них) и атомарные операции. Т.е. т.к. на мьютексах такое не сделаешь, то остаются только атомарные операции. Ниже пример реализации мьютекса на атомарных операциях, если кому интересно. Имхо реализация примитивов синхронизации на ассемблере должна выглядеть примерно так же. Code (Text): package ru.scf37.todo; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import junit.framework.Assert; import org.junit.Test; public class AtomicTest { private AtomicBoolean atomic = new AtomicBoolean(); //atomic boolean private Boolean locked = false; //boolean variable(also serves as mutex) to validate locked state. @Test public void testAtomicLock() { Runnable job = new Runnable() { @Override public void run() { atomicLock(); synchronized (locked) { //entering mutex Assert.assertFalse(locked); //should be false locked = true; } try { Thread.sleep(250); } catch (InterruptedException e) { } synchronized (locked) { //entering mutex Assert.assertTrue(locked); //should be still locked locked = false; } atomicUnlock(); } }; List<Thread> threads = new ArrayList<Thread>(); for (int i = 0 ; i < 25 ; i++) { Thread thread = new Thread(job); thread.start(); threads.add(thread); } for (Thread t : threads) { try { t.join(); } catch (InterruptedException e) { } } } private void atomicLock() { while (true) { boolean oldValue = atomic.getAndSet(true); if (oldValue == true) { //oops, it is already locked by someone - wait and try again try { Thread.sleep(200); //sleeeeep or do something else here.... } catch (InterruptedException e) { } } else { break; } } } private void atomicUnlock() { atomic.set(false); } }
scf гдето так оно и делается _lock proc LockAddr, isLock mov ecx, LockAddr mov eax, isLock xchg [ecx], eax ret _lock endp что делать если возвращается признак заблокированности ресурса - ваше дело. можете организовывать буфера (особенно актуально, когда с инетом дело имеешь), можете выполнять другие операции, можете ждать, можете попробовать уточнить обстановку на предмет висяка, например. разные среды предоставляют разные реализации этих возможностей. дальнейшее поскипано заради покоя
wsd Хорошая штука для самообразования и особенно подготовки к собеседованиям. НО - самое главное - это книга, которая упоминается в последнем посте. Maurice Herlihy, Nir Shavit - The Art of Multiprocessor Programming - 2008 Она написана с упором на java, но отдельные главы однозначно будут интересны всем, занимающимся разработкой многопоточных/асинхронных приложений.
t00x Перед xadd надо добавлять префикс LOCK. Ровно как и перед другими. Но так в процессоре полно команд которые можно использовать вместе с LOCK. Для решения проблем синхронизации.