Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #120014 > unrolled thread

counting_semaphore question

Started byMuttley@dastardlyhq.com
First post2024-09-11 10:15 +0000
Last post2024-09-12 07:05 -0700
Articles 20 on this page of 80 — 7 participants

Back to article view | Back to comp.lang.c++


Contents

  counting_semaphore question Muttley@dastardlyhq.com - 2024-09-11 10:15 +0000
    Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-11 13:48 +0200
      Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-11 12:03 +0000
        Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-11 14:10 +0200
          Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-11 12:29 +0000
            Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-11 15:54 +0200
              Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-11 14:12 +0000
            Re: counting_semaphore question David Brown <david.brown@hesbynett.no> - 2024-09-11 16:23 +0200
              Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-16 14:22 -0700
                Re: counting_semaphore question David Brown <david.brown@hesbynett.no> - 2024-09-17 09:22 +0200
                  Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-17 11:56 -0700
                    Re: counting_semaphore question David Brown <david.brown@hesbynett.no> - 2024-09-18 09:32 +0200
                      Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-19 12:57 +0200
                        Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-19 13:01 +0200
                        Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-19 12:09 -0700
                        Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-19 13:27 -0700
                          Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-19 13:30 -0700
            Re: counting_semaphore question Ben Bacarisse <ben@bsb.me.uk> - 2024-09-12 11:25 +0100
              Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-12 11:00 +0000
                Re: counting_semaphore question Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-09-12 07:34 -0700
                  Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-12 14:53 +0000
                    Re: counting_semaphore question David Brown <david.brown@hesbynett.no> - 2024-09-13 08:39 +0200
                      Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-13 07:26 +0000
                        Re: counting_semaphore question David Brown <david.brown@hesbynett.no> - 2024-09-13 12:54 +0200
                          Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-13 13:21 +0000
                            Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-13 15:29 +0200
                              Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-13 13:41 +0000
                              Re: counting_semaphore question David Brown <david.brown@hesbynett.no> - 2024-09-15 17:33 +0200
                            Re: counting_semaphore question David Brown <david.brown@hesbynett.no> - 2024-09-13 16:46 +0200
                              Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-13 14:59 +0000
                    Re: counting_semaphore question Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-09-13 07:43 -0700
          Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-11 13:51 -0700
            Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-12 04:21 +0200
              Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-12 11:57 -0700
                Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-13 14:29 +0200
                  Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-13 12:44 -0700
                    Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-14 01:43 +0200
                      Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-13 22:21 -0700
                        Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-14 12:07 -0700
                      Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-14 09:18 +0000
                        Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-14 11:40 +0200
                          Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-14 10:58 +0000
                            Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-14 13:15 +0200
                              Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-14 15:13 +0000
                                Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-14 17:26 +0200
                                  Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-14 15:48 +0000
                                    Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-14 17:50 +0200
                                      Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-14 15:55 +0000
                                        Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-14 17:57 +0200
                                          Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-15 09:05 +0000
                                            Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-15 11:48 +0200
                                              Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-15 09:52 +0000
                                                Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-15 14:50 +0200
                                                  Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-15 15:28 +0000
                                                    Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-16 05:02 +0200
                                                  Re: counting_semaphore question scott@slp53.sl.home (Scott Lurndal) - 2024-09-15 16:27 +0000
                                              Re: counting_semaphore question scott@slp53.sl.home (Scott Lurndal) - 2024-09-15 16:26 +0000
                              Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-14 12:12 -0700
                                Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-14 17:21 -0700
                                Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-15 07:11 +0200
                                  Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-14 22:20 -0700
                                    Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-15 09:35 +0200
                                      Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-15 12:59 -0700
                                        Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-16 05:04 +0200
                                          Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-16 13:30 -0700
                          Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-14 12:09 -0700
    Re: counting_semaphore question Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-09-11 07:37 -0700
      Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-11 15:03 +0000
        Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-11 17:27 +0200
          Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-11 16:04 +0000
            Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-11 18:16 +0200
              Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-11 18:16 +0000
                Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-12 04:20 +0200
            Re: counting_semaphore question "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-12 13:00 -0700
        Re: counting_semaphore question Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-09-11 20:56 -0700
          Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-12 07:43 +0000
            Re: counting_semaphore question David Brown <david.brown@hesbynett.no> - 2024-09-12 13:30 +0200
              Re: counting_semaphore question Muttley@dastardlyhq.com - 2024-09-12 14:48 +0000
            Re: counting_semaphore question Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-12 15:38 +0200
            Re: counting_semaphore question Andrey Tarasevich <andreytarasevich@hotmail.com> - 2024-09-12 07:05 -0700

Page 1 of 4  [1] 2 3 4  Next page →


#120014 — counting_semaphore question

FromMuttley@dastardlyhq.com
Date2024-09-11 10:15 +0000
Subjectcounting_semaphore question
Message-ID<vbrqjj$3hvsd$1@dont-email.me>
I've been looking at counting_semaphore and it looks useful but something
that doesn't seem to be properly explained anywhere is the template
parameter value. eg you can do:

std::counting_semaphore sem(2)

which will let a max of 2 threads into the protected block at a time or:

std::counting_semaphore<some number> sem(2)

such as 

std::counting_semaphore<10> sem(2)

I don't understand what the '10' will do. Its returned by the max() 
method but whats its purpose since if its the maximum possible threads
you could have in the protected block it makes no sense because you can't
change that value after creation as far as I can see.

Thanks for any help.

[toc] | [next] | [standalone]


#120015

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-11 13:48 +0200
Message-ID<vbs01c$3j5mc$1@raubtier-asyl.eternal-september.org>
In reply to#120014
Am 11.09.2024 um 12:15 schrieb Muttley@dastardlyhq.com:
> I've been looking at counting_semaphore and it looks useful but something
> that doesn't seem to be properly explained anywhere is the template
> parameter value. eg you can do:
> 
> std::counting_semaphore sem(2)
> 
> which will let a max of 2 threads into the protected block at a time or:
> 
> std::counting_semaphore<some number> sem(2)
> 
> such as
> 
> std::counting_semaphore<10> sem(2)
> 
> I don't understand what the '10' will do. ..

The ten gives an upper limit beyond the semaphore wont't increment.

Usually you won't need a C++20 semaphore yourself. For most purpose
the mutex and the condition_variable is sufficient.
But if you will build your own synchronization-primitives you inter-
nally would also need a semaphore. The semaphore class itself is
usually built on top of the system-provided futex. I implemented
a reader's writer lock with configurable priority for either rea-
ders or writers (std::shared_mutex only supports reader-priority)
and therefore I needed C++20's counting_semaphore and binary_sema-
phore (which is an template-alias for counting_senaphore<1>).

[toc] | [prev] | [next] | [standalone]


#120016

FromMuttley@dastardlyhq.com
Date2024-09-11 12:03 +0000
Message-ID<vbs0tm$3jf62$1@dont-email.me>
In reply to#120015
On Wed, 11 Sep 2024 13:48:04 +0200
Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>Am 11.09.2024 um 12:15 schrieb Muttley@dastardlyhq.com:
>> I've been looking at counting_semaphore and it looks useful but something
>> that doesn't seem to be properly explained anywhere is the template
>> parameter value. eg you can do:
>> 
>> std::counting_semaphore sem(2)
>> 
>> which will let a max of 2 threads into the protected block at a time or:
>> 
>> std::counting_semaphore<some number> sem(2)
>> 
>> such as
>> 
>> std::counting_semaphore<10> sem(2)
>> 
>> I don't understand what the '10' will do. ..
>
>The ten gives an upper limit beyond the semaphore wont't increment.

What upper limit? The max number of threads allowed in the protected section
above is 2, not 10. Or do you mean it'll only count up to 10 threads waiting
and ignore any beyond that? What happens if thread 11 comes along?

>Usually you won't need a C++20 semaphore yourself. For most purpose
>the mutex and the condition_variable is sufficient.

Condition variables IMO are unintuitive (eg the internal state change from
waiting on condition variable to waiting on mutex is completely invisible)
and hence very prone to logical bugs. I tend to avoid them where possible.

[toc] | [prev] | [next] | [standalone]


#120017

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-11 14:10 +0200
Message-ID<vbs1al$3jgnp$1@raubtier-asyl.eternal-september.org>
In reply to#120016
Am 11.09.2024 um 14:03 schrieb Muttley@dastardlyhq.com:

> What upper limit? The max number of threads allowed in the protected section
> above is 2, not 10. Or do you mean it'll only count up to 10 threads waiting
> and ignore any beyond that? What happens if thread 11 comes along?

The static parmeter is the maximum counter and the the two is the
initial counter. So two threads can currently acquire that semaphore.

> Condition variables IMO are unintuitive (eg the internal state change from
> waiting on condition variable to waiting on mutex is completely invisible)
> and hence very prone to logical bugs. I tend to avoid them where possible.

If you have a producer-consumer-pattern condition variables are the most
efficient way to handle this pattern.

[toc] | [prev] | [next] | [standalone]


#120018

FromMuttley@dastardlyhq.com
Date2024-09-11 12:29 +0000
Message-ID<vbs2fm$3jp23$1@dont-email.me>
In reply to#120017
On Wed, 11 Sep 2024 14:10:05 +0200
Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>Am 11.09.2024 um 14:03 schrieb Muttley@dastardlyhq.com:
>
>> What upper limit? The max number of threads allowed in the protected section
>> above is 2, not 10. Or do you mean it'll only count up to 10 threads waiting
>> and ignore any beyond that? What happens if thread 11 comes along?
>
>The static parmeter is the maximum counter and the the two is the
>initial counter. So two threads can currently acquire that semaphore.

Sorry, I still don't get it. What do you mean by maximum counter? 

Maximum threads that can wait on the semaphore and 11 gets an error?
Maximum threads that can ever access the protected section and after 10 have
accessed it the section is blocked to all threads?


>> Condition variables IMO are unintuitive (eg the internal state change from
>> waiting on condition variable to waiting on mutex is completely invisible)
>> and hence very prone to logical bugs. I tend to avoid them where possible.
>
>If you have a producer-consumer-pattern condition variables are the most
>efficient way to handle this pattern.

Efficient maybe, but the code can be obtuse and debugging a pain.

[toc] | [prev] | [next] | [standalone]


#120019

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-11 15:54 +0200
Message-ID<vbs7ds$3kplq$1@raubtier-asyl.eternal-september.org>
In reply to#120018
Am 11.09.2024 um 14:29 schrieb Muttley@dastardlyhq.com:

> On Wed, 11 Sep 2024 14:10:05 +0200

>> The static parmeter is the maximum counter and the the two is the
>> initial counter. So two threads can currently acquire that semaphore.

> Sorry, I still don't get it. What do you mean by maximum counter?

If you have a maximum counter of ten and an initial counter of two
you may increment the counter further eight times until another
release doesn't increment the counter.

>> If you have a producer-consumer-pattern condition variables are
>> the most efficient way to handle this pattern.

> Efficient maybe, but the code can be obtuse and debugging a pain.

The trick with condition variables is that the condition is met,
i.e. there are items to consume, there are no further kernel-calls.
That's basically the same with Java monitors with the slight dif-
ference, that monitors can be implemented somewhat more efficient
than a mutex / condvar combination.

[toc] | [prev] | [next] | [standalone]


#120020

FromMuttley@dastardlyhq.com
Date2024-09-11 14:12 +0000
Message-ID<vbs8fq$3l2la$1@dont-email.me>
In reply to#120019
On Wed, 11 Sep 2024 15:54:12 +0200
Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>Am 11.09.2024 um 14:29 schrieb Muttley@dastardlyhq.com:
>
>> On Wed, 11 Sep 2024 14:10:05 +0200
>
>>> The static parmeter is the maximum counter and the the two is the
>>> initial counter. So two threads can currently acquire that semaphore.
>
>> Sorry, I still don't get it. What do you mean by maximum counter?
>
>If you have a maximum counter of ten and an initial counter of two
>you may increment the counter further eight times until another
>release doesn't increment the counter.

I don't see how it works in practice.

acquire() increments the counter and it won't go beyond 2 (or whatever
you set the maximum thread acquire count to) once 2 have aquired it and
release() decrements it.

I've tried setting the max counters to all sorts of values including zero and
it makes no difference whatsoever to how this code executes:

#include <stdio.h>
#include <unistd.h>

#include <thread>
#include <semaphore>

using namespace std;

counting_semaphore<1> sem(2);

void func(int i)
{
        printf("Thread %d waiting\n",i);
        sem.acquire();
        printf("Thread %d acquired\n",i);
        sleep(1);
        printf("Thread %d releasing\n",i);
        sem.release();
}

int main()
{
        thread thr[10];
        printf("Max = %d\n",sem.max());
        for(int i=0;i < 10;++i) thr[i] = thread(func,i);
        for(int i=0;i < 10;++i) thr[i].join();
        return 0;
}

[toc] | [prev] | [next] | [standalone]


#120021

FromDavid Brown <david.brown@hesbynett.no>
Date2024-09-11 16:23 +0200
Message-ID<vbs95s$3l7ms$1@dont-email.me>
In reply to#120018
On 11/09/2024 14:29, Muttley@dastardlyhq.com wrote:
> On Wed, 11 Sep 2024 14:10:05 +0200
> Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>> Am 11.09.2024 um 14:03 schrieb Muttley@dastardlyhq.com:
>>
>>> What upper limit? The max number of threads allowed in the protected section
>>> above is 2, not 10. Or do you mean it'll only count up to 10 threads waiting
>>> and ignore any beyond that? What happens if thread 11 comes along?
>>
>> The static parmeter is the maximum counter and the the two is the
>> initial counter. So two threads can currently acquire that semaphore.
> 
> Sorry, I still don't get it. What do you mean by maximum counter?
> 
> Maximum threads that can wait on the semaphore and 11 gets an error?
> Maximum threads that can ever access the protected section and after 10 have
> accessed it the section is blocked to all threads?
> 

You are talking about a counting semaphore here - the number will be the 
maximum value of the count.  (The actual maximum value could be bigger 
than the template parameter, but not smaller than it.)  If this maximum 
value is 10, then you can acquire the semaphore 10 times without 
blocking - any future acquires will block until there are releases.

Semaphores can be acquired and released by any threads - one thread can 
acquire often, another thread can release them, or you can have any 
combination.  They are not used for protection sections or data - they 
are used as signalling mechanisms.  One or more "producer" thread might 
make objects, and one or more "consumer" threads used them, in which 
case your 10 here is the maximum number of these objects that will be 
buffered up at a time.

> 
>>> Condition variables IMO are unintuitive (eg the internal state change from
>>> waiting on condition variable to waiting on mutex is completely invisible)
>>> and hence very prone to logical bugs. I tend to avoid them where possible.
>>
>> If you have a producer-consumer-pattern condition variables are the most
>> efficient way to handle this pattern.
> 
> Efficient maybe, but the code can be obtuse and debugging a pain.
> 

<https://en.cppreference.com/w/cpp/thread/counting_semaphore>

This suggests that semaphores may be an alteranative to condition 
variables but with better performance.  (Individual implementations may 
vary, of course.)

[toc] | [prev] | [next] | [standalone]


#120108

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2024-09-16 14:22 -0700
Message-ID<vca7hs$32c6u$1@dont-email.me>
In reply to#120021
On 9/11/2024 7:23 AM, David Brown wrote:
> On 11/09/2024 14:29, Muttley@dastardlyhq.com wrote:
>> On Wed, 11 Sep 2024 14:10:05 +0200
>> Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>>> Am 11.09.2024 um 14:03 schrieb Muttley@dastardlyhq.com:
>>>
>>>> What upper limit? The max number of threads allowed in the protected 
>>>> section
>>>> above is 2, not 10. Or do you mean it'll only count up to 10 threads 
>>>> waiting
>>>> and ignore any beyond that? What happens if thread 11 comes along?
>>>
>>> The static parmeter is the maximum counter and the the two is the
>>> initial counter. So two threads can currently acquire that semaphore.
>>
>> Sorry, I still don't get it. What do you mean by maximum counter?
>>
>> Maximum threads that can wait on the semaphore and 11 gets an error?
>> Maximum threads that can ever access the protected section and after 
>> 10 have
>> accessed it the section is blocked to all threads?
>>
> 
> You are talking about a counting semaphore here - the number will be the 
> maximum value of the count.  (The actual maximum value could be bigger 
> than the template parameter, but not smaller than it.)  If this maximum 
> value is 10, then you can acquire the semaphore 10 times without 
> blocking - any future acquires will block until there are releases.
> 
> Semaphores can be acquired and released by any threads - one thread can 
> acquire often, another thread can release them, or you can have any 
> combination.  They are not used for protection sections or data - they 
> are used as signalling mechanisms.  One or more "producer" thread might 
> make objects, and one or more "consumer" threads used them, in which 
> case your 10 here is the maximum number of these objects that will be 
> buffered up at a time.

[...]

Think of creating a queue with 100,000 elements in it. The semaphore to 
protect this queue should have an initial state of 100,000. The least 
min value, should be high because the queue might have 1.9 million 
elements in there. So, for this queue:

std::counting_semaphore<PTRDIFF_MAX> sem(100000);

right? There are 100000 elements in the queue because its initialized 
that way. A single thread can pop and work on 100000 elements before it 
blocks on a queue empty condition.

[toc] | [prev] | [next] | [standalone]


#120119

FromDavid Brown <david.brown@hesbynett.no>
Date2024-09-17 09:22 +0200
Message-ID<vcbant$3cto1$1@dont-email.me>
In reply to#120108
On 16/09/2024 23:22, Chris M. Thomasson wrote:
> On 9/11/2024 7:23 AM, David Brown wrote:
>> On 11/09/2024 14:29, Muttley@dastardlyhq.com wrote:
>>> On Wed, 11 Sep 2024 14:10:05 +0200
>>> Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>>>> Am 11.09.2024 um 14:03 schrieb Muttley@dastardlyhq.com:
>>>>
>>>>> What upper limit? The max number of threads allowed in the 
>>>>> protected section
>>>>> above is 2, not 10. Or do you mean it'll only count up to 10 
>>>>> threads waiting
>>>>> and ignore any beyond that? What happens if thread 11 comes along?
>>>>
>>>> The static parmeter is the maximum counter and the the two is the
>>>> initial counter. So two threads can currently acquire that semaphore.
>>>
>>> Sorry, I still don't get it. What do you mean by maximum counter?
>>>
>>> Maximum threads that can wait on the semaphore and 11 gets an error?
>>> Maximum threads that can ever access the protected section and after 
>>> 10 have
>>> accessed it the section is blocked to all threads?
>>>
>>
>> You are talking about a counting semaphore here - the number will be 
>> the maximum value of the count.  (The actual maximum value could be 
>> bigger than the template parameter, but not smaller than it.)  If this 
>> maximum value is 10, then you can acquire the semaphore 10 times 
>> without blocking - any future acquires will block until there are 
>> releases.
>>
>> Semaphores can be acquired and released by any threads - one thread 
>> can acquire often, another thread can release them, or you can have 
>> any combination.  They are not used for protection sections or data - 
>> they are used as signalling mechanisms.  One or more "producer" thread 
>> might make objects, and one or more "consumer" threads used them, in 
>> which case your 10 here is the maximum number of these objects that 
>> will be buffered up at a time.
> 
> [...]
> 
> Think of creating a queue with 100,000 elements in it. The semaphore to 
> protect this queue should have an initial state of 100,000. The least 
> min value, should be high because the queue might have 1.9 million 
> elements in there. So, for this queue:
> 
> std::counting_semaphore<PTRDIFF_MAX> sem(100000);
> 
> right? There are 100000 elements in the queue because its initialized 
> that way. A single thread can pop and work on 100000 elements before it 
> blocks on a queue empty condition.

Roughly yes - assuming you are setting up the queue with the first 
100,000 elements and then creating the semaphore, then allowing the 
queue to grow or shrink unhindered.  It's more common for queues to 
start with a semaphore of count 0 (an empty queue) and then add 
elements, but if you have 100,000 elements in advance then this would be 
a more efficient initialisation.

You can also omit the template parameter, in which case an 
implementation-defined default is used.  A quick test on godbolt's gcc 
shows that this gives a max() of 0x7fff'ffff, and that this is the 
largest value supported by the C++ library used by that implementation - 
it keeps the count as a signed 32-bit integer.  Attempting to use 
PTRDIFF_MAX triggers a static assertion:

	static_assert(__least_max_value <= __semaphore_impl::_S_max);

I don't know if this is a conformance flaw in the C++ standard library, 
or if I just haven't read the documentation details well enough.  And I 
couldn't see any specification for what the default value should be, but 
I can't think of any other reasonable choice than the biggest acceptable 
value.

[toc] | [prev] | [next] | [standalone]


#120125

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2024-09-17 11:56 -0700
Message-ID<vccjdk$3lb34$2@dont-email.me>
In reply to#120119
On 9/17/2024 12:22 AM, David Brown wrote:
> On 16/09/2024 23:22, Chris M. Thomasson wrote:
>> On 9/11/2024 7:23 AM, David Brown wrote:
>>> On 11/09/2024 14:29, Muttley@dastardlyhq.com wrote:
>>>> On Wed, 11 Sep 2024 14:10:05 +0200
>>>> Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>>>>> Am 11.09.2024 um 14:03 schrieb Muttley@dastardlyhq.com:
>>>>>
>>>>>> What upper limit? The max number of threads allowed in the 
>>>>>> protected section
>>>>>> above is 2, not 10. Or do you mean it'll only count up to 10 
>>>>>> threads waiting
>>>>>> and ignore any beyond that? What happens if thread 11 comes along?
>>>>>
>>>>> The static parmeter is the maximum counter and the the two is the
>>>>> initial counter. So two threads can currently acquire that semaphore.
>>>>
>>>> Sorry, I still don't get it. What do you mean by maximum counter?
>>>>
>>>> Maximum threads that can wait on the semaphore and 11 gets an error?
>>>> Maximum threads that can ever access the protected section and after 
>>>> 10 have
>>>> accessed it the section is blocked to all threads?
>>>>
>>>
>>> You are talking about a counting semaphore here - the number will be 
>>> the maximum value of the count.  (The actual maximum value could be 
>>> bigger than the template parameter, but not smaller than it.)  If 
>>> this maximum value is 10, then you can acquire the semaphore 10 times 
>>> without blocking - any future acquires will block until there are 
>>> releases.
>>>
>>> Semaphores can be acquired and released by any threads - one thread 
>>> can acquire often, another thread can release them, or you can have 
>>> any combination.  They are not used for protection sections or data - 
>>> they are used as signalling mechanisms.  One or more "producer" 
>>> thread might make objects, and one or more "consumer" threads used 
>>> them, in which case your 10 here is the maximum number of these 
>>> objects that will be buffered up at a time.
>>
>> [...]
>>
>> Think of creating a queue with 100,000 elements in it. The semaphore 
>> to protect this queue should have an initial state of 100,000. The 
>> least min value, should be high because the queue might have 1.9 
>> million elements in there. So, for this queue:
>>
>> std::counting_semaphore<PTRDIFF_MAX> sem(100000);
>>
>> right? There are 100000 elements in the queue because its initialized 
>> that way. A single thread can pop and work on 100000 elements before 
>> it blocks on a queue empty condition.
> 
> Roughly yes - assuming you are setting up the queue with the first 
> 100,000 elements and then creating the semaphore, then allowing the 
> queue to grow or shrink unhindered.  It's more common for queues to 
> start with a semaphore of count 0 (an empty queue) and then add 
> elements, but if you have 100,000 elements in advance then this would be 
> a more efficient initialisation.

I sure think so. :^)


> You can also omit the template parameter, in which case an 
> implementation-defined default is used.  A quick test on godbolt's gcc 
> shows that this gives a max() of 0x7fff'ffff, and that this is the 
> largest value supported by the C++ library used by that implementation - 
> it keeps the count as a signed 32-bit integer.  Attempting to use 
> PTRDIFF_MAX triggers a static assertion:
> 
>      static_assert(__least_max_value <= __semaphore_impl::_S_max);

Oh shit! I assumed setting it to PTRDIFF_MAX is okay. Shit! Well, damn. 
thanks for the info David. Sometimes I think the template parameter is 
there for specialization purposes ala binary semaphore with its template 
param as 1.


> I don't know if this is a conformance flaw in the C++ standard library, 
> or if I just haven't read the documentation details well enough.  And I 
> couldn't see any specification for what the default value should be, but 
> I can't think of any other reasonable choice than the biggest acceptable 
> value.

Agreed. Again, thanks for the info. :^)

[toc] | [prev] | [next] | [standalone]


#120127

FromDavid Brown <david.brown@hesbynett.no>
Date2024-09-18 09:32 +0200
Message-ID<vcdvlg$3vqbh$1@dont-email.me>
In reply to#120125
On 17/09/2024 20:56, Chris M. Thomasson wrote:
> On 9/17/2024 12:22 AM, David Brown wrote:
>> On 16/09/2024 23:22, Chris M. Thomasson wrote:
>>> On 9/11/2024 7:23 AM, David Brown wrote:
>>>> On 11/09/2024 14:29, Muttley@dastardlyhq.com wrote:
>>>>> On Wed, 11 Sep 2024 14:10:05 +0200
>>>>> Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>>>>>> Am 11.09.2024 um 14:03 schrieb Muttley@dastardlyhq.com:
>>>>>>
>>>>>>> What upper limit? The max number of threads allowed in the 
>>>>>>> protected section
>>>>>>> above is 2, not 10. Or do you mean it'll only count up to 10 
>>>>>>> threads waiting
>>>>>>> and ignore any beyond that? What happens if thread 11 comes along?
>>>>>>
>>>>>> The static parmeter is the maximum counter and the the two is the
>>>>>> initial counter. So two threads can currently acquire that semaphore.
>>>>>
>>>>> Sorry, I still don't get it. What do you mean by maximum counter?
>>>>>
>>>>> Maximum threads that can wait on the semaphore and 11 gets an error?
>>>>> Maximum threads that can ever access the protected section and 
>>>>> after 10 have
>>>>> accessed it the section is blocked to all threads?
>>>>>
>>>>
>>>> You are talking about a counting semaphore here - the number will be 
>>>> the maximum value of the count.  (The actual maximum value could be 
>>>> bigger than the template parameter, but not smaller than it.)  If 
>>>> this maximum value is 10, then you can acquire the semaphore 10 
>>>> times without blocking - any future acquires will block until there 
>>>> are releases.
>>>>
>>>> Semaphores can be acquired and released by any threads - one thread 
>>>> can acquire often, another thread can release them, or you can have 
>>>> any combination.  They are not used for protection sections or data 
>>>> - they are used as signalling mechanisms.  One or more "producer" 
>>>> thread might make objects, and one or more "consumer" threads used 
>>>> them, in which case your 10 here is the maximum number of these 
>>>> objects that will be buffered up at a time.
>>>
>>> [...]
>>>
>>> Think of creating a queue with 100,000 elements in it. The semaphore 
>>> to protect this queue should have an initial state of 100,000. The 
>>> least min value, should be high because the queue might have 1.9 
>>> million elements in there. So, for this queue:
>>>
>>> std::counting_semaphore<PTRDIFF_MAX> sem(100000);
>>>
>>> right? There are 100000 elements in the queue because its initialized 
>>> that way. A single thread can pop and work on 100000 elements before 
>>> it blocks on a queue empty condition.
>>
>> Roughly yes - assuming you are setting up the queue with the first 
>> 100,000 elements and then creating the semaphore, then allowing the 
>> queue to grow or shrink unhindered.  It's more common for queues to 
>> start with a semaphore of count 0 (an empty queue) and then add 
>> elements, but if you have 100,000 elements in advance then this would 
>> be a more efficient initialisation.
> 
> I sure think so. :^)
> 
> 
>> You can also omit the template parameter, in which case an 
>> implementation-defined default is used.  A quick test on godbolt's gcc 
>> shows that this gives a max() of 0x7fff'ffff, and that this is the 
>> largest value supported by the C++ library used by that implementation 
>> - it keeps the count as a signed 32-bit integer.  Attempting to use 
>> PTRDIFF_MAX triggers a static assertion:
>>
>>      static_assert(__least_max_value <= __semaphore_impl::_S_max);
> 
> Oh shit! I assumed setting it to PTRDIFF_MAX is okay. Shit! Well, damn. 
> thanks for the info David. Sometimes I think the template parameter is 
> there for specialization purposes ala binary semaphore with its template 
> param as 1.

That seems likely.  It also allows for specialisation for different 
sizes, though that did not appear to be used for by the library with the 
gcc on godbolt.  A small max value could perhaps be implemented with 
fixed size queues instead of variable ones, and (without having 
considered implementations in detail) it is plausible that a semaphore 
counter with a 32-bit counter could be more efficient than one with a 
64-bit counter.  But most likely specialisation is a binary semaphore 
(the <semaphore> header already has "using binary_semaphore = 
counting_semaphore<1>;").

> 
> 
>> I don't know if this is a conformance flaw in the C++ standard 
>> library, or if I just haven't read the documentation details well 
>> enough.  And I couldn't see any specification for what the default 
>> value should be, but I can't think of any other reasonable choice than 
>> the biggest acceptable value.
> 
> Agreed. Again, thanks for the info. :^)
> 

[toc] | [prev] | [next] | [standalone]


#120129

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-19 12:57 +0200
Message-ID<vch03e$hp9g$1@raubtier-asyl.eternal-september.org>
In reply to#120127
Am 18.09.2024 um 09:32 schrieb David Brown:

> That seems likely.  It also allows for specialisation for different 
> sizes, though that did not appear to be used for by the library with
> the  gcc on godbolt.  A small max value could perhaps be implemented
> with fixed size queues instead of variable ones, ...

The queue is for for sure maintained by the kernel and is a linked list.

> ... and (without having  considered implementations in detail) it is
> plausible that a semaphore counter with a 32-bit counter could be more
> efficient than one with a 64-bit counter.

I guess that it's unlikely that the counter is 64 bit.

> But most likely specialisation is a binary semaphore  (the <semaphore>
> header already has "using binary_semaphore = counting_semaphore<1>;").

That's how the standard specifies binary_semaphore as an alias to
counting_semaphore<1>.

[toc] | [prev] | [next] | [standalone]


#120130

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-19 13:01 +0200
Message-ID<vch0an$hp9g$2@raubtier-asyl.eternal-september.org>
In reply to#120129
Am 19.09.2024 um 12:57 schrieb Bonita Montero:

> I guess that it's unlikely that the counter is 64 bit.

The initialitation value of a Posix semaphore is an unsigned int.
The initialitation value of a System V semaphore is an int.

[toc] | [prev] | [next] | [standalone]


#120131

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2024-09-19 12:09 -0700
Message-ID<vchstg$m9fr$1@dont-email.me>
In reply to#120129
On 9/19/2024 3:57 AM, Bonita Montero wrote:
> Am 18.09.2024 um 09:32 schrieb David Brown:
> 
>> That seems likely.  It also allows for specialisation for different 
>> sizes, though that did not appear to be used for by the library with
>> the  gcc on godbolt.  A small max value could perhaps be implemented
>> with fixed size queues instead of variable ones, ...
> 
> The queue is for for sure maintained by the kernel and is a linked list.
> 
>> ... and (without having  considered implementations in detail) it is
>> plausible that a semaphore counter with a 32-bit counter could be more
>> efficient than one with a 64-bit counter.
> 
> I guess that it's unlikely that the counter is 64 bit.

Well, I was wondering about using std::ptrdiff_t. It's a little "easier" 
to implement a fast semaphore using signed integers. :^)


>> But most likely specialisation is a binary semaphore  (the <semaphore>
>> header already has "using binary_semaphore = counting_semaphore<1>;").
> 
> That's how the standard specifies binary_semaphore as an alias to
> counting_semaphore<1>.

Exactly.

[toc] | [prev] | [next] | [standalone]


#120132

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2024-09-19 13:27 -0700
Message-ID<vci1fl$mi5s$1@dont-email.me>
In reply to#120129
On 9/19/2024 3:57 AM, Bonita Montero wrote:
> Am 18.09.2024 um 09:32 schrieb David Brown:
> 
>> That seems likely.  It also allows for specialisation for different 
>> sizes, though that did not appear to be used for by the library with
>> the  gcc on godbolt.  A small max value could perhaps be implemented
>> with fixed size queues instead of variable ones, ...
> 
> The queue is for for sure maintained by the kernel and is a linked list.

We used to refer to these as kernel waitsets back in the day. Still, 
keep the benaphore in mind:

https://www.haiku-os.org/legacy-docs/benewsletter/Issue1-26.html#Engineering1-26


> 
>> ... and (without having  considered implementations in detail) it is
>> plausible that a semaphore counter with a 32-bit counter could be more
>> efficient than one with a 64-bit counter.
> 
> I guess that it's unlikely that the counter is 64 bit.
> 
>> But most likely specialisation is a binary semaphore  (the <semaphore>
>> header already has "using binary_semaphore = counting_semaphore<1>;").
> 
> That's how the standard specifies binary_semaphore as an alias to
> counting_semaphore<1>.
> 
> 

[toc] | [prev] | [next] | [standalone]


#120133

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2024-09-19 13:30 -0700
Message-ID<vci1lg$mi5s$2@dont-email.me>
In reply to#120132
On 9/19/2024 1:27 PM, Chris M. Thomasson wrote:
> On 9/19/2024 3:57 AM, Bonita Montero wrote:
>> Am 18.09.2024 um 09:32 schrieb David Brown:
>>
>>> That seems likely.  It also allows for specialisation for different 
>>> sizes, though that did not appear to be used for by the library with
>>> the  gcc on godbolt.  A small max value could perhaps be implemented
>>> with fixed size queues instead of variable ones, ...
>>
>> The queue is for for sure maintained by the kernel and is a linked list.
> 
> We used to refer to these as kernel waitsets back in the day. Still, 
> keep the benaphore in mind:
> 
> https://www.haiku-os.org/legacy-docs/benewsletter/Issue1-26.html#Engineering1-26

Implementing correct condvars on windows was an interesting thing back 
in the day. It seemed that the bugged algos would be around 100:1 ratio. 
Using an explicit waitset was one way, however, it limited one to 
SCHED_OTHER.

> 

[toc] | [prev] | [next] | [standalone]


#120033

FromBen Bacarisse <ben@bsb.me.uk>
Date2024-09-12 11:25 +0100
Message-ID<87ikv1i2yk.fsf@bsb.me.uk>
In reply to#120018
Muttley@dastardlyhq.com writes:

> On Wed, 11 Sep 2024 14:10:05 +0200
> Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>>Am 11.09.2024 um 14:03 schrieb Muttley@dastardlyhq.com:
>>
>>> What upper limit? The max number of threads allowed in the protected section
>>> above is 2, not 10. Or do you mean it'll only count up to 10 threads waiting
>>> and ignore any beyond that? What happens if thread 11 comes along?
>>
>>The static parmeter is the maximum counter and the the two is the
>>initial counter. So two threads can currently acquire that semaphore.
>
> Sorry, I still don't get it. What do you mean by maximum counter?

You might want to consider who you are talking to.

Let's take std::counting_semaphore<M> sem(N); as an example.  The N is
the important number but it is not a 'maximum' in any hard sense -- it
is simply the initial value of the counter.  If it were some sort of
hard maximum, std::counting_semaphore sem(0); would be useless but it
isn't -- it simply means that at least one release() is needed before an
acquire() won't block.  Of course, if often /does/ represent the
maximum number of threads that can access some resource because the
usual pattern is to use std::counting_semaphore sem(N) with the standard
pattern of every thread calling acquire() and then release().

The template parameter M is very different and rather unusual.  It is,
first and foremost, just a hint to the implementation about how much
space will be needed for the counter, so the most useful value for M is
1 because some systems can implement binary semaphores more efficiently
than counting ones.

But this "limit" is not enforced other than by making the behaviour
undefined when it is exceeded.  Pre-conditions on the operations state
that the counter must always be >= 0 and <= M, but you won't be able to
check this unless the implementation decides to enforce these
pre-conditions with some sort of error report.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#120034

FromMuttley@dastardlyhq.com
Date2024-09-12 11:00 +0000
Message-ID<vbuhk4$7hu2$1@dont-email.me>
In reply to#120033
On Thu, 12 Sep 2024 11:25:07 +0100
Ben Bacarisse <ben@bsb.me.uk> boringly babbled:
>Muttley@dastardlyhq.com writes:
>> Sorry, I still don't get it. What do you mean by maximum counter?
>
>You might want to consider who you are talking to.

I guess so.

>The template parameter M is very different and rather unusual.  It is,

And very poorly explained in all the online documentation.

>But this "limit" is not enforced other than by making the behaviour
>undefined when it is exceeded.  Pre-conditions on the operations state

Clang seems to ignore it. You can call release() as much as you like and
it'll just keep increasing the counter.

[toc] | [prev] | [next] | [standalone]


#120038

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2024-09-12 07:34 -0700
Message-ID<vbuu5g$a0rk$1@dont-email.me>
In reply to#120034
On 09/12/24 4:00 AM, Muttley@dastardlyhq.com wrote:
> 
> Clang seems to ignore it. You can call release() as much as you like and
> it'll just keep increasing the counter.
> 

It "ignores" it exactly the same way as the following declaration

   std::uint_fast8_t n = 2;

might "ignore" the 8 in the type name and allow you to increment the 
variable well past 255. Come to think of it, the underlying reasons for 
why it can be so are very similar.

It is perfectly explained in the spec. And it's been thoroughly 
explained here. What's the difficulty?

-- 
Best regards,
Andrey

[toc] | [prev] | [next] | [standalone]


Page 1 of 4  [1] 2 3 4  Next page →

Back to top | Article view | comp.lang.c++


csiph-web