Introduction
to System V IPC
931
/* While msgget() fails, try creating the queue exclusively */
while ((msqid = msgget(key, IPC_CREAT | IPC_EXCL | MQ_PERMS)) == -1) {
if (errno == EEXIST) { /* MQ with the same key already
exists - remove it and try again */
msqid = msgget(key, 0);
if (msqid == -1)
errExit("msgget() failed to retrieve old queue ID");
if (msgctl(msqid, IPC_RMID, NULL) == -1)
errExit("msgget() failed to delete old queue");
printf("Removed old message queue (id=%d)\n", msqid);
} else { /* Some other error --> give up */
errExit("msgget() failed");
}
}
/* Upon loop exit, we've successfully
created the message queue,
and we can then carry on to do other work... */
exit(EXIT_SUCCESS);
}
–––––––––––––––––––––––––––––––––––––––––––––––––
svipc/svmsg_demo_server.c
Even if a restarted server re-created the IPC objects, there still would be a potential
problem if supplying the same key to the get call always generated the same identi-
fier whenever a new IPC object was created. Consider
the solution just outlined
from the point of view of the client. If the IPC objects re-created by the server use
the same identifiers, then the client would have no way
of becoming aware that the
server has been restarted and that the IPC objects don’t contain the expected his-
torical information.
To solve this problem, the kernel employs an algorithm (described in the next
section) that normally ensures that when a new IPC object is created, the object’s
identifier will be different, even when the same key is supplied. Consequently, any
clients of the old server process that attempt to use the old
identifier will receive an
error from the relevant IPC system call.
Solutions such as that shown in Listing 45-1 don’t completely solve the problem
of identifying a server restart when using System V shared memory, since a
shared memory object is deleted only when all processes have detached it from
their virtual address space. However, shared memory
objects are typically used
in conjunction with System V semaphores, which are immediately deleted in
response to an
IPC_RMID
operation. This means that
a client process will become
aware of a server restart when it tries to access the deleted semaphore object.
Chia sẻ với bạn bè của bạn: