На самом деле похож на ответ @Scoots, но без сортировки, окна, также:
SELECT (
SELECT jsonb_agg(items order by items)
FROM jsonb_array_elements(food) AS items
) AS food,
count(*)
FROM test_json_grouping
GROUP BY 1;
... объяснил:
QUERY PLAN
------------------------------------------------------------------------------------------------------
HashAggregate (cost=1635.60..1890.60 rows=200 width=40)
Group Key: (SubPlan 1)
-> Seq Scan on test_json_grouping (cost=0.00..1629.25 rows=1270 width=32)
SubPlan 1
-> Aggregate (cost=1.25..1.26 rows=1 width=32)
-> Function Scan on jsonb_array_elements items (cost=0.00..1.00 rows=100 width=32)
(6 rows)
Результат:
[112 ]Семафор можно сосчитать, а мьютекс можно сосчитать только до 1.
Предположим, у вас запущен поток, который принимает клиентские подключения. Этот поток может обрабатывать 10 клиентов одновременно. Затем каждый новый клиент устанавливает семафор до тех пор, пока он не достигнет 10. Когда семафор имеет 10 флагов, ваш поток не будет принимать новые соединения.
Mutex обычно используется для защиты содержимого. Предположим, что ваши 10 клиентов могут получить доступ к нескольким частям системы. Затем вы можете защитить часть системы с помощью мьютекса, чтобы при подключении 1 клиента к этой подсистеме никто другой не имел доступа. Вы также можете использовать семафор для этой цели. Мьютекс - это «Семафор взаимного исключения» .
Мьютекс используется для последовательного доступа к ресурсу, в то время как семафор ограничивает доступ к ресурсу до заданного числа. Вы можете думать о мьютексе как о семафоре с счетчиком доступа 1. Независимо от того, что вы установили для своего счетчика семафоров, потоки могут получить доступ к ресурсу до того, как ресурс заблокирован.
Unfortunately everyone has missed the most important difference between the semaphore and the mutex; the concept of "ownership".
Semaphores have no notion of ownership, this means that any thread can release a semaphore (this can lead to many problems in itself but can help with "death detection"). Whereas a mutex does have the concept of ownership (i.e. you can only release a mutex you have acquired).
Владение невероятно важно для безопасного программирования параллельных систем. Я бы всегда рекомендовал использовать мьютекс вместо семафора (но это влияет на производительность).
Мьютексы также могут поддерживать наследование приоритетов (что может помочь с проблемой инверсии приоритетов) и рекурсию (устранение одного типа взаимоблокировок).
Следует также указать, что существуют «двоичные» семафоры и «счетные / общие» семафоры. Семафор Java является подсчитывающим семафором и, таким образом, позволяет инициализировать его значением больше единицы (тогда как, как указывалось, мьютекс может иметь только концептуальный счетчик единиц). Полезность этого была отмечена в других постах.
Итак, подведем итог: если у вас нет нескольких ресурсов для управления, я бы всегда рекомендовал мьютекс над семафором.
Мьютекс - это в основном взаимное исключение. Только один поток может получить ресурс одновременно. Когда один поток получает ресурс, никакому другому потоку не разрешается получать ресурс, пока поток, владеющий ресурсом, не освободится. Все потоки, ожидающие получения ресурса, будут заблокированы.
Семафор используется для управления количеством выполняемых потоков. Там будет фиксированный набор ресурсов. Количество ресурсов будет уменьшаться каждый раз, когда потоку принадлежит один и тот же. Когда счетчик семафоров достигает 0, другие потоки не могут получить ресурс. Потоки блокируются до тех пор, пока другие потоки не владеют ресурсами.
Короче говоря, основное отличие заключается в том, сколько потоков может получить ресурс одновременно?
Семафор - это механизм подсчета синхронизации, а мьютекс - нет.