⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch13.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<HTML>



<HEAD>

   <TITLE>Chapter 13 -- Messaging Facilities: The System

V Ipc Functions</TITLE>

   <META NAME="GENERATOR" CONTENT="Mozilla/3.0b5aGold (WinNT; I) [Netscape]">

</HEAD>

<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">

<H1><FONT COLOR=#FF0000>Chapter 13</FONT></H1>

<H1><B><FONT SIZE=5 COLOR=#FF0000>Messaging Facilities: The System

V Ipc Functions</FONT></B>

</H1>

<P>

<HR WIDTH="100%"></P>

<P>

<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>

</FONT></FONT></H3>



<UL>

<LI><A HREF="#AnIntroductiontotheSystemVIpc" >An Introduction to the System V Ipc</A>

<LI><A HREF="#UsingtheUNIXSystemVIpcFunctions" >Using the UNIX System V Ipc Functions</A>

<UL>

<LI><A HREF="#ThemsggetFunction" >The msgget() Function</A>

</UL>

<LI><A HREF="#TheipcsCommand" >The ipcs Command</A>

<LI><A HREF="#ThemsgsndandmsgrcvFunctions" >The msgsnd() and msgrcv() Functions</A>

<LI><A HREF="#SharedMemory" >Shared Memory</A>

<UL>

<LI><A HREF="#TheshmwriteandshmreadFunctions" >The shmwrite() and shmread() Functions</A>

</UL>

<LI><A HREF="#Semaphores" >Semaphores</A>

<LI><A HREF="#TheSysVIpcModule" >The SysV::Ipc Module</A>

<LI><A HREF="#ApplicationsofIpc" >Applications of Ipc</A>

<LI><A HREF="#Summary" >Summary</A>

</UL>

<HR>

<P>

This chapter introduces you to the Interprocess Communications

(Ipc) functionality of message queues, shared memory, and semaphores.

The Ipc facilities provide a clean, consistent solution to passing

data between processes on the same machine. (Sockets can extend

across platforms and a network.)

<H2><A NAME="AnIntroductiontotheSystemVIpc"><FONT SIZE=5 COLOR=#FF0000>An

Introduction to the System V Ipc</FONT></A></H2>

<P>

The UNIX system V Ipc enables you to perform the following tasks:

<UL>

<LI><FONT COLOR=#000000>Send messages from one process to another

via a message queue. Processes can add messages to, check the

length of, and remove messages from a queue. </FONT>

<LI><FONT COLOR=#000000>Create and handle shared memory. This

includes the capability to read from and write into areas of shared

memory. </FONT>

<LI><FONT COLOR=#000000>Create and handle semaphores. This includes

the capability to read, set, and reset semaphore values. </FONT>

</UL>

<P>

Each Ipc function is available to calling processes as a system

resource. These resources are available for all processes on a

system-level basis and can be shared by many processes on the

same system. Ipc resources are limited to the system they reside

on and do not offer networking functionality. Because there are

only a limited number of Ipc resources on any UNIX system, it's

important to free up each resource after using it. This is because

each Ipc resource can exist for a long time after the process

that created it has finished executing. 

<P>

Each Ipc resource is referred to as an object in the operating

system. For working with Ipc resources, you either have to create

an object or use an existing one. Ipc objects are created via

a <TT><FONT FACE="Courier">get()</FONT></TT> function for that

object. Each <TT><FONT FACE="Courier">get()</FONT></TT> function

call requires a unique positive Ipc key as the identifier for

that object. Keys are converted by the kernel into an ID number

and returned by the <TT><FONT FACE="Courier">get()</FONT></TT>

function. Then the ID is used by other related functions to refer

to that object for all other operations.

<P>

An Ipc key is a long integer and is used to name the Ipc resource.

A key is assigned by the programmer but could also be assigned

by the system. The keys for shared memory, message queues, and

semaphores are unique in the sense that the same key number can

be assigned to Ipc objects of different types. That is, a semaphore

with a key of 11 can coexist on the same system with a message

queue with a key of 11. However, another semaphore cannot coexist

with a key of 11 on the same system. Programmers can force the

underlying operating system to assign a key by specifying the

<TT><FONT FACE="Courier">&amp;Ipc_PRIVATE</FONT></TT> flag (this

is explained shortly).

<P>

When you pass in a key number to a <TT><FONT FACE="Courier">get()</FONT></TT>

function, an ID is returned. Once an object is created and its

ID is returned, the object must then be referred to by its ID.

You can draw the analogy that a file handle is to a file as an

ID is to an Ipc resource. The returned IDs are positive if there

are no errors. (A negative ID is returned if there is an error.)

<P>

You can create a unique key by using the <TT><FONT FACE="Courier">&amp;Ipc_PRIVATE</FONT></TT>

flags if you are not imaginative enough. The kernel then creates

the ID and the key for you.

<P>

Ipc objects are global. Once created, the object is available

to all the processes in the system. In this respect, you have

to be careful how you access the available resources because any

process can overwrite your shared memory, message queue, or semaphore.

Also, your Ipc object remains in memory long after your process

has gone. You, not the kernel, are responsible for cleanup.

<P>

When you create the object, you also have to specify permissions.

The format of the permissions is very similar to that of files:

three groups of read/write for owner, group, and other. The execute

permission bits for the permissions are ignored by the Ipc calls.

To get access to an existing object, you have to specify <TT><FONT FACE="Courier">0</FONT></TT>

for permissions.

<P>

The following flags are permitted for creating objects:<P>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR VALIGN=TOP><TD WIDTH=119><I>Flag</I></TD><TD WIDTH=471><I>Description</I>

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=119><TT><FONT FACE="Courier">&amp;Ipc_CREAT</FONT></TT>

</TD><TD WIDTH=471>This flag creates an Ipc object given a key, or it attaches to an existing object with the same key.

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=119><TT><FONT FACE="Courier">&amp;Ipc_EXCL</FONT></TT>

</TD><TD WIDTH=471>This flag creates an Ipc object given a key. It returns an error if the object with this key already exists. This prevents two unrelated processes from creating two objects with the same key.

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=119><TT><FONT FACE="Courier">&amp;Ipc_RMID</FONT></TT>

</TD><TD WIDTH=471>Given an ID, this flag removes the object from the system. You must have the permissions on the object to be able to delete it.

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=119><TT><FONT FACE="Courier">&amp;Ipc_STAT</FONT></TT>

</TD><TD WIDTH=471>Given an ID, this flag returns the values of each member of an Ipc object.

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=119><TT><FONT FACE="Courier">&amp;Ipc_SET</FONT></TT>

</TD><TD WIDTH=471>Given an ID and a data structure for an object, this flag sets the values of each member of the corresponding Ipc object.

</TD></TR>

</TABLE></CENTER>

<H2><A NAME="UsingtheUNIXSystemVIpcFunctions"><FONT SIZE=5 COLOR=#FF0000>Using

the UNIX System V Ipc Functions</FONT></A></H2>

<P>

With Perl you can access all of the Ipc functions via a standard

set of library functions. The information required for the functions

is consistent with a UNIX system interface; therefore, the information

in a UNIX <TT><FONT FACE="Courier">man</FONT></TT> page will provide

enough information about the facilities available on your system.

<P>

System V Ipc functions are defined in Perl header files. For a

Perl installation on a UNIX system, the required information is

in the <TT><FONT FACE="Courier">*.ph</FONT></TT> files. (The <TT><FONT FACE="Courier">ph</FONT></TT>

stands for Perl header.) The following files will be required

by most of the Perl scripts you write to utilize the Ipc facilities:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">require &quot;ipc.ph&quot;;<BR>

require &quot;msg.ph&quot;;<BR>

require &quot;sem.ph&quot;;<BR>

require &quot;shm.ph&quot;;</FONT></TT>

</BLOCKQUOTE>

<P>

Keep in mind that this might not work as shown here. Here are

the primary reasons an error occurs when you try to include these

files with the <TT><FONT FACE="Courier">require</FONT></TT> statement:

<UL>

<LI><FONT COLOR=#000000>The </FONT><TT><FONT FACE="Courier">*.ph</FONT></TT>

files do not exist.

<LI><FONT COLOR=#000000>The </FONT><TT><FONT FACE="Courier">*.ph</FONT></TT>

files do exist but are not in the path(s) specified by the <TT><FONT FACE="Courier">@Inc</FONT></TT>

<TT><FONT FACE="Courier">include</FONT></TT> variable.

</UL>

<P>

To cure these problems, you'll have to run the <TT><FONT FACE="Courier">h2ph</FONT></TT>

script in the <TT><FONT FACE="Courier">/usr/lib/perl</FONT></TT>

directory. The <TT><FONT FACE="Courier">h2ph</FONT></TT> script

contains a line (around line 9) that has the variable <TT><FONT FACE="Courier">$perlincl</FONT></TT>

set to a directory. On my machine, this variable is set to <TT><FONT FACE="Courier">/usr/lib/perl5/i486-linux/5.002</FONT></TT>.

On your machine, this value might be different. In any event,

the value of <TT><FONT FACE="Courier">$perlincl</FONT></TT> is

the directory where the <TT><FONT FACE="Courier">*.ph</FONT></TT>

files are stored by the <TT><FONT FACE="Courier">h2ph</FONT></TT>

script.

<P>

Now go to the <TT><FONT FACE="Courier">/usr/include</FONT></TT>

directory and, as root, run the <TT><FONT FACE="Courier">h2ph</FONT></TT>

command as shown here:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">h2ph * sys/*</FONT></TT>

</BLOCKQUOTE>

<P>

The include files on your system may require that more subdirectories

be included in the paths specified to this program. For example,

on a Linux 3.0 system, the command to get most of the required

files is this:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">h2ph * sys/*  asm/* linux/*</FONT></TT>

</BLOCKQUOTE>

<P>

The only clear way to know which files are required is to include

the Perl header files in a sample script. If everything goes well,

you should be able to get the script to run. The sample script

shown in Listing 13.1 gives two ignorable warnings on all three

different Linux versions. The script does manage to create the

message queue as expected. I cover the topic of message queues

in the section &quot;Shared Memory,&quot; later in this chapter.

<HR>

<BLOCKQUOTE>

<B>Listing 13.1. A sample script to test Perl header file inclusion.

<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1 #!/usr/bin/perl<BR>

&nbsp;2 <BR>

&nbsp;3 unshift (@Inc,&quot;/usr/lib/perl5/i486-linux/5.002/sys&quot;);

<BR>

&nbsp;4 unshift (@Inc,&quot;/usr/lib/perl5/i486-linux/5.002/linux&quot;);

<BR>

&nbsp;5 unshift (@Inc,&quot;/usr/lib/perl5/i486-linux/5.002/asm&quot;);

<BR>

&nbsp;6 <BR>

&nbsp;7 print &quot;@Inc&quot;;

<BR>

&nbsp;8 <BR>

&nbsp;9 require &quot;ipc.ph&quot;;

<BR>

10 require &quot;msg.ph&quot;;<BR>

11 require &quot;shm.ph&quot;;<BR>

12 require &quot;sem.ph&quot;;<BR>

13 <BR>

14 $PERMISSIONS=0666;<BR>

15 $ipckey = &amp;Ipc_PRIVATE;<BR>

16 <BR>

17 $msgid = msgget($ipckey,&amp;Ipc_CREAT | &amp;Ipc_EXCL | $PERMISSIONS);

<BR>

18 <BR>

19 printf &quot;\n&nbsp;&nbsp;Message Id = $msgid&quot;;</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

The three required files in the sample script are included for

message queues, shared memory, and semaphores, respectively. Only

those that are required have to be included. That is, you do not

have to include <TT><FONT FACE="Courier">shm.ph</FONT></TT> if

you aren't going to be using shared memory. The <TT><FONT FACE="Courier">ipc.ph</FONT></TT>

file is required for any of these three features.

<P>

<TT><FONT FACE="Courier">PERMISSIONS</FONT></TT> is set to <TT><FONT FACE="Courier">0666</FONT></TT>,

meaning that any process can work with or even delete the Ipc

object in question. For a more secure system, you might consider

using <TT><FONT FACE="Courier">0600</FONT></TT> to give permissions

to the owner process only.

<H3><A NAME="ThemsggetFunction">The <TT><FONT SIZE=4 FACE="Courier">msgget()</FONT></TT><FONT SIZE=4>

Function</FONT></A></H3>

<P>

In Listing 13.1 an Ipc message queue was created. To use the System

V message-passing facility, you first create a message queue ID

for a given message queue. Here's the syntax of the <TT><FONT FACE="Courier">msgget()</FONT></TT>

function:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$msgid = msgget (<I>$key, $flag</I>);</FONT></TT>

</BLOCKQUOTE>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -