📄 ch10.htm
字号:
5<BR>
6 Win32::Semaphore::Create($sObject,1,1,"Bile")||die
"Die: $!\n";<BR>
7<BR>
8 sub ErrorMsg {<BR>
9 print Win32::FormatMessage( Win32::GetLastError());<BR>
10 }<BR>
11<BR>
12 &ErrorMsg; # Tell me if there were
any errors. :w<BR>
13<BR>
14 #<BR>
15 # wait for semaphore.<BR>
16 #<BR>
17 if( $sObject->Wait(INFINITE)){<BR>
18 #<BR>
19 #Access
the shared resource here.<BR>
20 # Do something here with returned value.
<BR>
21 #
&Access( $Shared_Resource );<BR>
22<BR>
23 #<BR>
24 # Don't forget to release the semaphore
<BR>
25 # as quickly as possible.<BR>
26 #<BR>
27 $sObject->Release(
1,$last );<BR>
28<BR>
29 #<BR>
30 # You can work with your copy of private
data.<BR>
31 # with no need for locking.<BR>
32 #<BR>
33 }<BR>
34 else {<BR>
35 print" Whoa! I cannot access any
semaphores!\n";<BR>
36 }</FONT></TT>
</BLOCKQUOTE>
<HR>
<H2><A NAME="UsingMutexwithWin32Mutex"><FONT SIZE=5 COLOR=#FF0000>Using
</FONT><TT><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">Mutex</FONT></TT><FONT SIZE=5 COLOR=#FF0000>
with </FONT><TT><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">Win32::Mutex</FONT></TT></A>
</H2>
<P>
The <TT><FONT FACE="Courier">Win32::Mutex</FONT></TT> module is
used to create, destroy, and work with <TT><FONT FACE="Courier">Mutex</FONT></TT>es
in the NT system. A <TT><FONT FACE="Courier">Mutex</FONT></TT>
is used to provide mutually exclusive access to a resource. Processes
vie to own a <TT><FONT FACE="Courier">Mutex</FONT></TT>, and only
one process can own a <TT><FONT FACE="Courier">Mutex</FONT></TT>
at one time. A process controlling a <TT><FONT FACE="Courier">Mutex</FONT></TT>
can then work exclusively on a shared resource such as a file
or device. Mutexes differ from semaphores in that <TT><FONT FACE="Courier">Mutex</FONT></TT>es
are available only in kernel-mode processes and not for user-mode
processes. Refer to Jason Loveman's book,<I> Moving into Windows
NT Programming</I>, for some good examples on how to use <TT><FONT FACE="Courier">Mutex</FONT></TT>es.
<P>
To create a <TT><FONT FACE="Courier">Mutex</FONT></TT>, you have
to call the <TT><FONT FACE="Courier">Create</FONT></TT> function
for the object. The first parameter into the <TT><FONT FACE="Courier">Create</FONT></TT>
call is assigned a reference to the <TT><FONT FACE="Courier">Mutex</FONT></TT>
object. The syntax for the <TT><FONT FACE="Courier">Create</FONT></TT>
call is
<BLOCKQUOTE>
<TT><FONT FACE="Courier">Win32::Mutex::Create($mutexObject, $owner,
$mutexName )</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">$mutexObject</FONT></TT> is assigned
a reference to the new <TT><FONT FACE="Courier">Mutex</FONT></TT>
object. The value in the <TT><FONT FACE="Courier">$owner</FONT></TT>
variable can be <TT><FONT FACE="Courier">1</FONT></TT> or <TT><FONT FACE="Courier">0</FONT></TT>.
If it is <TT><FONT FACE="Courier">1</FONT></TT>, the calling process
will be assigned the initial ownership at the time of creation.
<P>
If it is <TT><FONT FACE="Courier">0</FONT></TT>, the <TT><FONT FACE="Courier">Mutex</FONT></TT>
will be created as available. The name of the <TT><FONT FACE="Courier">Mutex</FONT></TT>
will be in <TT><FONT FACE="Courier">$mutexName</FONT></TT>.
<P>
<TT><FONT FACE="Courier">Create</FONT></TT> creates a <TT><FONT FACE="Courier">Mutex</FONT></TT>
object and returns the reference in <TT><FONT FACE="Courier">$MutexObj</FONT></TT>.
If the <TT><FONT FACE="Courier">$InitialOwner</FONT></TT> flag
is set (nonzero), the process calling the <TT><FONT FACE="Courier">Create</FONT></TT>
function has immediate ownership of the <TT><FONT FACE="Courier">Mutex</FONT></TT>.
Otherwise, the <TT><FONT FACE="Courier">Mutex</FONT></TT> is available.
<TT><FONT FACE="Courier">$Name</FONT></TT> can be used by other
processes in <TT><FONT FACE="Courier">Win32::Mutex::Opencall</FONT></TT>
to create an object to reference an already created <TT><FONT FACE="Courier">Mutex</FONT></TT>.
<P>
To open a <TT><FONT FACE="Courier">Mutex</FONT></TT>, use the
<TT><FONT FACE="Courier">Open</FONT></TT> call to get the <TT><FONT FACE="Courier">Mutex</FONT></TT>
object. The syntax for the <TT><FONT FACE="Courier">Open</FONT></TT>
call is
<BLOCKQUOTE>
<TT><FONT FACE="Courier">Win32::Mutex::Open($mObject,$mutexName);</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">$mObject</FONT></TT> variable is
assigned a reference to a <TT><FONT FACE="Courier">Mutex</FONT></TT>
object with the name value in <TT><FONT FACE="Courier">$mutexName</FONT></TT>.
The <TT><FONT FACE="Courier">Mutex</FONT></TT> specified in <TT><FONT FACE="Courier">$mutexName</FONT></TT>
must already have been created or else a <TT><FONT FACE="Courier">NULL</FONT></TT>
value is returned in <TT><FONT FACE="Courier">$mObject</FONT></TT>.
<P>
The <TT><FONT FACE="Courier">Release()</FONT></TT> method on a
<TT><FONT FACE="Courier">Mutex</FONT></TT> object releases a <TT><FONT FACE="Courier">Mutex</FONT></TT>
object back to the system for use by other processes. The <TT><FONT FACE="Courier">Mutex</FONT></TT>
object is destroyed when it goes out of scope in the Perl program
because the default <TT><FONT FACE="Courier">DESTROY</FONT></TT>
method of the <TT><FONT FACE="Courier">Mutex</FONT></TT> object
frees the system resources used by the <TT><FONT FACE="Courier">Mutex</FONT></TT>.
<P>
The <TT><FONT FACE="Courier">Wait()</FONT></TT> function for the
<TT><FONT FACE="Courier">Mutex</FONT></TT> object is used to wait
for ownership of a <TT><FONT FACE="Courier">Mutex</FONT></TT>.
The syntax of this function is
<BLOCKQUOTE>
<TT><FONT FACE="Courier">Wait( $TimeOut );</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">$TimeOut</FONT></TT> variable is
specified in milliseconds. The value can be set to <TT><FONT FACE="Courier">INFINITE</FONT></TT>
for waiting indefinitely. The <TT><FONT FACE="Courier">Wait()</FONT></TT>
function returns a <TT><FONT FACE="Courier">false</FONT></TT>
value if the function timed out or returns true if the <TT><FONT FACE="Courier">Mutex</FONT></TT>
has become available.
<P>
Here's a fragment of code that shows how to use a <TT><FONT FACE="Courier">Mutex</FONT></TT>:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#<BR>
# This is reserved for privileged users only<BR>
#<BR>
# Create a Mutex object<BR>
#<BR>
<BR>
Win32::Mutex::Create( $Mut,0, "MyMutex")|| die $!;<BR>
<BR>
<BR>
#<BR>
# Use it<BR>
#<BR>
sub doPriviliged() {<BR>
local( $mObject ) = $_[0]; # The first arg in method
is the object<BR>
$mObject->wait( 5000 )|| return ; #
Could not get it<BR>
<BR>
<BR>
#<BR>
# do your thing.<BR>
#<BR>
<BR>
$mObject->Release();<BR>
}</FONT></TT>
</BLOCKQUOTE>
<H2><A NAME="UsingWin32ChangeNotification"><FONT SIZE=5 COLOR=#FF0000>Using
</FONT><TT><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">Win32::ChangeNotification</FONT></TT></A>
</H2>
<P>
The <TT><FONT FACE="Courier">Win32::ChangeNotification</FONT></TT>
module is used for notifying a Perl application or process when
a branch in the specific file system tree has been modified. The
module relies on the <TT><FONT FACE="Courier">FindFirst()</FONT></TT>
call in the Win32 API, and this is the way to create the object.
The syntax is
<BLOCKQUOTE>
<TT><FONT FACE="Courier">Win32::ChangeNotification::FindFirst(
<BR>
$cObject,<BR>
$pathName, $watchSubtree,
<BR>
$filter);</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">$cObject</FONT></TT> variable is
set to the new <TT><FONT FACE="Courier">ChangeNotification</FONT></TT>
object created. <TT><FONT FACE="Courier">$pathName</FONT></TT>
is the path to the directory that you want to monitor. <TT><FONT FACE="Courier">$watchSubTree</FONT></TT>
function can be set to <TT><FONT FACE="Courier">0</FONT></TT>
or <TT><FONT FACE="Courier">1</FONT></TT>. If set to <TT><FONT FACE="Courier">0</FONT></TT>,
any subdirectories of the path are not modified. If set to <TT><FONT FACE="Courier">1</FONT></TT>,
the monitor process looks at the subtree, too.
<P>
The <TT><FONT FACE="Courier">$filter</FONT></TT> variable specifies
the conditions on which the program notifies. The value in <TT><FONT FACE="Courier">$filter</FONT></TT>
can be set to a value that is a combination of the following constants:
<P>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR VALIGN=TOP><TD WIDTH=295><TT><FONT FACE="Courier">FILE_NOTIFY_chANGE_FILE_NAME</FONT></TT>
</TD><TD WIDTH=295>Notifies when a file in the monitored directory is renamed, created, or deleted.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=295><TT><FONT FACE="Courier">FILE_NOTIFY_chANGE_DIR_NAME</FONT></TT>
</TD><TD WIDTH=295>Notifies whether the name of the directory is changed.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=295><TT><FONT FACE="Courier">FILE_NOTIFY_chANGE_ATTRIBUTES</FONT></TT>
</TD><TD WIDTH=295>Notifies whether the attributes of the directory are changed.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=295><TT><FONT FACE="Courier">FILE_NOTIFY_chANGE_SIZE</FONT></TT>
</TD><TD WIDTH=295>Notifies whether the size of the underlying directory is actually written to disk. This notification might not happen immediately due to the way NT flushes cached writes of data to the disk.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=295><TT><FONT FACE="Courier">FILE_NOTIFY_chANGE_LAST_WRITE</FONT></TT>
</TD><TD WIDTH=295>Notifies whether the last write time of the underlying file is modified and actually written to disk. This notification might not happen immediately due to the way NT flushes cached writes of data to the disk.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=295><TT><FONT FACE="Courier">FILE_NOTIFY_chANGE_SECURITY</FONT></TT>
</TD><TD WIDTH=295>Notifies of any security descriptor changes in the directory being monitored.
</TD></TR>
</TABLE></CENTER>
<P>
<P>
Other methods for this module include the following:<P>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR VALIGN=TOP><TD WIDTH=177><TT><FONT FACE="Courier">FindNext();</FONT></TT>
</TD><TD WIDTH=413>The <TT><FONT FACE="Courier">FindNext</FONT></TT> method requests that the operating system signal the <TT><FONT FACE="Courier">change notification</FONT></TT> object the next time it detects an appropriate change.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=177><TT><FONT FACE="Courier">Close();</FONT></TT>
</TD><TD WIDTH=413>Stops the <TT><FONT FACE="Courier">notification</FONT></TT> object monitoring.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=177><TT><FONT FACE="Courier">Wait( $TimeOut);</FONT></TT>
</TD><TD WIDTH=413><TT><FONT FACE="Courier">$TimeOut</FONT></TT> is the time out in milliseconds. The <TT><FONT FACE="Courier">Wait</FONT></TT> method causes the calling process to block until notification of the change.
</TD></TR>
</TABLE></CENTER>
<P>
<P>
When the <TT><FONT FACE="Courier">ChangeNotification</FONT></TT>
object goes out of scope, the object's <TT><FONT FACE="Courier">DESTROY</FONT></TT>
method is called by Perl. The <TT><FONT FACE="Courier">DESTROY</FONT></TT>
method closes any outstanding notification.
<P>
Listing 10.4 shows how to use the <TT><FONT FACE="Courier">ChangeNotification</FONT></TT>
object.
<HR>
<BLOCKQUOTE>
<B>Listing 10.4. Using the </B><TT><B><FONT FACE="Courier">ChangeNotification</FONT></B></TT><B>
object.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 use Win32;<BR>
2 use Win32::ChangeNotification;<BR>
3<BR>
4 my $watch = TRUE ;<BR>
5 my $flags = "FILE_NOTIFY_chANGE_ATTRIBUTES | FILE_NOTIFY_chANGE_SIZE"
;<BR>
6 my $Path = "D:/perl5/";<BR>
7<BR>
8 Win32::ChangeNotification::FindFirst( $pobj,<BR>
9 $Path,<BR>
10 ,1,<BR>
11 $flags) || die $!;<BR>
12<BR>
13 sub ErrorMsg {<BR>
14 print Win32::FormatMessage( Win32::GetLastError());<BR>
15 }<BR>
16<BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -