Google 網路論壇不再支援新的 Usenet 貼文或訂閱項目,但過往內容仍可供查看。

named semaphore problem

觀看次數:1,112 次
跳至第一則未讀訊息

spx2

未讀,
2009年2月14日 下午6:42:0114/2/2009
收件者︰

I'm trying to use sem_open for named semaphores and on my system it
doesn't work.
Along with this message I'm writing a small example of opening an
unnamed semaphore
which after compiled and run for me it prints "error opening
semaphore".
I am compiling the example with g++ -g -Wall test.cpp -lpthread
I have also tried the version of sem_open with 2 parameters to no
avail.
I have a fairly new version of kernel( 2.6.21-2-686 ) and I wouldn't
expect this to happen
Why is this happening ?

#include <unistd.h>
#include <sys/shm.h>
#include <iostream>
#include <semaphore.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>

#define SHM_MODE 0666
#define SEM_NAME1 "/tmp/nimeni"


using namespace std;
int main() {

sem_t* sem1;
if( ( sem1 = sem_open(SEM_NAME1,O_CREAT|O_EXCL,SHM_MODE,1) ) ==
NULL) {
cout<<"error opening semaphore\n";
exit(1);
};

}


Nate Eldredge

未讀,
2009年2月14日 下午7:03:1214/2/2009
收件者︰
spx2 <stefan...@gmail.com> writes:

> I'm trying to use sem_open for named semaphores and on my system it
> doesn't work.
> Along with this message I'm writing a small example of opening an
> unnamed semaphore

A named semaphore, of course.

> which after compiled and run for me it prints "error opening
> semaphore".
> I am compiling the example with g++ -g -Wall test.cpp -lpthread
> I have also tried the version of sem_open with 2 parameters to no
> avail.
> I have a fairly new version of kernel( 2.6.21-2-686 ) and I wouldn't
> expect this to happen
> Why is this happening ?

Semaphores are not files, and the name of a semaphore is not a pathname.
RTM.

From sem_open(3):

sem_open() creates a new POSIX semaphore or opens an existing
semaphore. The semaphore is identified by name. For details of
the construction of name, see sem_overview(7).

From sem_overview(7):

Named semaphores
A named semaphore is identified by a name of the form
/somename. Two processes can operate on the same named
semaphore by passing the same name to sem_open(3).

Changing SEM_NAME1 to "/nimeni" makes it succeed. Note that this
doesn't imply that anything gets created in the root directory.

Checking the value of errno would have shown that it gets set to ENOENT,
which should suggest that something is wrong with the name. man perror.

Jens Thoms Toerring

未讀,
2009年2月14日 下午8:08:2114/2/2009
收件者︰
Nate Eldredge <na...@vulcan.lan> wrote:
> Semaphores are not files, and the name of a semaphore is not a pathname.
> RTM.

> From sem_open(3):

> sem_open() creates a new POSIX semaphore or opens an existing
> semaphore. The semaphore is identified by name. For details of
> the construction of name, see sem_overview(7).

> From sem_overview(7):

> Named semaphores
> A named semaphore is identified by a name of the form
> /somename. Two processes can operate on the same named
> semaphore by passing the same name to sem_open(3).

> Changing SEM_NAME1 to "/nimeni" makes it succeed. Note that this
> doesn't imply that anything gets created in the root directory.

> Checking the value of errno would have shown that it gets set to ENOENT,
> which should suggest that something is wrong with the name. man perror.

I think it's not just a question of R(F)TM here since a bit of a
re-write of the man pages could IMHO make this a lot clearer. No-
thing in the wording with '/somename' indicates that there are no
slashes allowed in 'somename'. And getting ENOENT is a bit of a
red hering - I normally would expect that when I try to open a file
that does not exist (or when I use a path that does not exist).
Translating that in this case to mean "you used a name that is not
well-formed" takes quite a bit of imagination. All that makes it
look as if the name has something to do with files (or at least
file names) and thus it can be rather confusing.

Moreover, the man page for sem_open (from May 2008) tells about
ENOENT:

The O_CREAT flag was not specified in oflag, and no semaphore
with this name exists.

but, clearly, O_CREAT was specified in the OPs case. And the
wording in SUSv3

ENOENT O_CREAT is not set and the named semaphore does not exist.

doesn't seem to say anything different.

And it gets worse by the fact that the slash at the start of the
name is actually not required - if I call sem_open() with "somename"
instead of "/somename" (and haven't done that before) it works...

From playing around with the different possibilities it looks as
if a starting slash may simply be dropped, while any slash in
'name' (except at the start) results in failure with ENOENT.

Now SUSv3 says:

It is unspecified whether the name appears in the file system

That makes it look to me as if calling sem_open() creates a file
with 'name' is actually an option...

and is visible to functions that take pathnames as arguments. The
name argument conforms to the construction rules for a pathname.

So, shouldn't then a 'name' with embedded slashes be just fine?

If name begins with the slash character, then processes calling
sem_open() with the same value of name shall refer to the same
semaphore object, as long as that name has not been removed.

WTF is meant with "that name has not been removed"? Do they mean
"the semaphore associated with that name has not been removed"?

If name does not begin with the slash character, the effect is
implementation-defined. The interpretation of slash characters other
than the leading slash character in name is implementation-defined.

I guess it would be nice if the man page would be a bit clearer
about what actually is required and what's actually defined by the
implementation on Linux. I guess I have to come up with a patch for
those man pages;-)
Regards, Jens
--
\ Jens Thoms Toerring ___ j...@toerring.de
\__________________________ http://toerring.de

WANG Cong

未讀,
2009年2月15日 上午4:27:0215/2/2009
收件者︰
Jens Thoms Toerring wrote:

<snip>

>
> I think it's not just a question of R(F)TM here since a bit of a
> re-write of the man pages could IMHO make this a lot clearer. No-
> thing in the wording with '/somename' indicates that there are no
> slashes allowed in 'somename'.


No, I don't think so.

> And getting ENOENT is a bit of a
> red hering - I normally would expect that when I try to open a file
> that does not exist (or when I use a path that does not exist).
> Translating that in this case to mean "you used a name that is not
> well-formed" takes quite a bit of imagination. All that makes it
> look as if the name has something to do with files (or at least
> file names) and thus it can be rather confusing.

If you understand what the path is used for, you will not say this.
See below.

<snip>

>
> And it gets worse by the fact that the slash at the start of the
> name is actually not required - if I call sem_open() with "somename"
> instead of "/somename" (and haven't done that before) it works...

Sure.

In fact, if you take a look at glibc source code, you will know what
that path is used for. It is used as a path within tmpfs which usually
is mounted at /dev/shm on your Linux, if the path starts with a slash,
it means from the root directory of tmpfs, this is highly recommended.
If not, it will be used as relative path where the current working
path is also the root directory.

So, in the OP's code, the path contains a slash in the middle, which
means that it assumes there is already a directory existed as '/tmp'.
But the fact is no, so the OP got ENOENT even if he specified O_CREAT.


>
> From playing around with the different possibilities it looks as
> if a starting slash may simply be dropped, while any slash in
> 'name' (except at the start) results in failure with ENOENT.


Yes, probably, in fact if there are more than one slashes in the
beginning, they will be all dropped, see the code of sem_open():

/* Construct the filename. */
while (name[0] == '/')
++name;

if (name[0] == '\0')
{
/* The name "/" is not supported. */
__set_errno (EINVAL);
return SEM_FAILED;
}


Regards,

Cong

Jens Thoms Toerring

未讀,
2009年2月15日 上午5:45:5615/2/2009
收件者︰

> <snip>

> Sure.

Ok, things get clearer if you have a look at the glibc sources
(but not having to do that is what the man pages are supposed
to be good for;-). To sumarize:

1) All leading slashes get stripped from 'name'
2) A file with a name constructed from "sem." and what's
in 'name' gets created for the semaphore (if possible,
if not possible ENOENT gets returned)

That also means that embedded slashes in 'name' are, at least
in principle, possible. If 'name' is "/aaa/bbb" then sem_open()
will try to create a file named "/sem.aaa/bbb" in dev/shm (or
wherever the tmpfs is mounted._ But for this to work a direc-
tory named "/sem.aaa" has to already exist there.

I still think it should be pointed out in the man page that
using slashes embedded in the semaphores name usually will
not work, especially if understanding why you may get ENOENT
in that case can only be understood by inspecting the glibc
code.

0 則新訊息