Previous | Contents | Index |
If more than one process or thread will write to a shared global section containing COMMON block data, the user program may need to synchronize access to COMMON block variables.
Compile all programs referencing the shared common area with the same value for the /ALIGNMENT and /GRANULARITY qualifiers. For example:
$ FORTRAN/ALIGN=COMMONS=NATURAL /GRANULARITY=LONGWORD INC_COMMON |
Using /GRANULARITY=LONGWORD for 4-byte variables or /GRANULARITY=QUADWORD for 8-byte variables ensures that adjacent data is not accidentally affected. To ensure access to 1-byte variables, specify /GRANULARITY=BYTE. Because accessing data items less than four bytes slows run-time performance, you might want to consider synchronizing read and write access to the data on the same node.
Typically, programs accessing shared data use common event flag clusters to synchronize read and write access to the data on the same node. In the simplest case, one event flag in a common event flag cluster might indicate that a program is writing data, and a second event flag in the cluster might indicate that a program is reading data. Before accessing the shared data, a program must examine the common event flag cluster to ensure that accessing the data does not conflict with an operation already in progress.
Other ways of synchronizing access on a single node include the OpenVMS lock manager system services (SYS$ENQ and SYS$DEQ), the hibernate and wake system services (SYS$HIBER and SYS$WAKE), or using Assembler code.
It is often useful to exchange data between processes, as when synchronizing execution or sending messages.
A mailbox is a record-oriented pseudo I/O device that allows you to
pass data from one process to another. Mailboxes are created by the
Create Mailbox system service (SYS$CREMBX). The following sections
describe how to create mailboxes and how to send and receive data using
mailboxes.
13.2.3.1 Creating a Mailbox
SYS$CREMBX creates the mailbox and returns the number of the I/O channel assigned to the mailbox. You must specify a variable for the I/O channel. You should also specify a logical name to be associated with the mailbox. The logical name identifies the mailbox for other processes and for HP Fortran I/O statements.
The SYS$CREMBX system service also allows you to specify the message and buffer sizes, the mailbox protection code, and the access mode of the mailbox; however, the default values for these arguments are usually sufficient.
The following segment of code creates a mailbox named MAILBOX. The number of the I/O channel assigned to the mailbox is returned in ICHAN.
INCLUDE '($SYSSRVNAM)' INTEGER (KIND=2) ICHAN ISTATUS = SYS$CREMBX(,ICHAN,,,,,'MAILBOX') |
Do not use MAIL as the logical name for a mailbox. If you do so, the system will not execute the proper image in response to the OpenVMS command MAIL. |
Sending data to and receiving data from a mailbox is like other forms of HP Fortran I/O. The mailbox is simply treated as a record-oriented I/O device.
Use HP Fortran formatted sequential READ and WRITE statements to send and receive messages. The data transmission is performed synchronously; a program that writes a message to a mailbox waits until the message is read, and a program that reads a message from a mailbox waits until the message is written before it continues transmission. When the writing program closes the mailbox, an end-of-file condition is returned to the reading program.
Do not attempt to write a record of zero length to a mailbox; the program reading the mailbox interprets this record as an end-of-file. Zero-length records are produced by consecutive slashes in FORMAT statements.
The following sample program creates a mailbox assigned with the logical name MAILBOX. The program then performs an open operation specifying the logical name MAILBOX as the file to be opened. It then reads file names from FNAMES.DAT and writes them to the mailbox until all of the records in the file have been transmitted.
CHARACTER (LEN=64) FILENAME INCLUDE '($SYSSRVNAM)' INTEGER (KIND=2) ICHAN INTEGER (KIND=4) STATUS STATUS = SYS$CREMBX(,ICHAN,,,,,'MAILBOX') IF (.NOT. STATUS) GO TO 99 OPEN (UNIT=9, FILE='MAILBOX', STATUS='NEW', & CARRIAGECONTROL='LIST', ERR=99) OPEN (UNIT=8, FILE='FNAMES.DAT', STATUS='OLD') 10 READ (8,100,END=98) FILENAME WRITE (9,100) FILENAME 100 FORMAT(A) GO TO 10 98 CLOSE (UNIT=8) CLOSE (UNIT=9) STOP 99 WRITE (6,*) 'Mailbox error' STOP END |
The following sample program reads messages from a mailbox that was assigned the logical name MAILBOX when it was created. The messages comprise file names, which the program reads. The program then types the files associated with the file names.
CHARACTER(LEN=64) FILNAM CHARACTER(LEN=123) TEXT OPEN (UNIT=1, FILE='MAILBOX', STATUS='OLD') 1 READ (1,100,END=12) FILNAM 100 FORMAT (A) OPEN (UNIT=2, FILE=FILNAM, STATUS='OLD') OPEN (UNIT=3, FILE='SYS$OUTPUT', STATUS='NEW') 2 READ (2,100,END=10) TEXT WRITE (3,100) TEXT GO TO 2 10 CLOSE (UNIT=2) CLOSE (UNIT=3) GO TO 1 12 END |
If your computer is a node in a DECnet network, you can communicate with other nodes in the network by means of standard HP Fortran I/O statements. These statements let you exchange data with a program at the remote computer (task-to-task communication) and access files at the remote computer (resource sharing). There is no apparent difference between these intersystem exchanges and the local interprocess and file access exchanges.
Remote file access and task-to-task communications are discussed separately in the sections that follow.
The system manager at the remote system needs to create the necessary network objects and security controls (such as proxy access). Network file specifications might need to use access control strings, depending on how the remote system access has been implemented.
To access a file on a remote system, include the remote node name in the file name specification. For example:
BOSTON::DBA0:[SMITH]TEST.DAT;2 |
To make a program independent of the physical location of the files it accesses, you can assign a logical name to the network file specification as shown in the following example:
$ DEFINE INVFILE MIAMI::DR4:[INV]INVENT.DAT |
The logical name INVFILE now refers to the remote file and can be used in the program. For example:
OPEN (UNIT=10, FILE='INVFILE', STATUS='OLD') |
To process a file on the local network node, reassign the logical name;
you do not need to modify the source program.
13.3.2 Network Task-to-Task Communication
Network task-to-task communication allows a program running on one network node to interact with a program running on another network node. This interaction is accomplished with standard HP Fortran I/O statements and looks much like an interactive program/user session.
The steps involved in network task-to-task communications are:
BOSTON::"TASK=UPDATE" |
BOSTON"username password"::"TASK=UPDATE" |
The form of the remote task file varies, depending on the remote
computer's operating system.
For OpenVMS systems, this task file is a command file with a file type
of COM. The network software submits the command file as a batch job on
the remote system.
The following is a complete example showing how HP Fortran programs can exchange information over a network. The originating program prompts for an integer value and sends the value to the remote program. The remote program then adds one to the value and returns the value to the originating program. It is assumed that the remote operating system is an OpenVMS system.
The originating program on the local node contains the following source code:
OPEN (UNIT=10, FILE='PARIS::"TASK=REMOTE"', STATUS='OLD', & FORM='UNFORMATTED', ACCESS='SEQUENTIAL', IOSTAT=IOS, ERR=999) ! Prompt for a number PRINT 101 101 FORMAT ($,' ENTER A NUMBER: ') ACCEPT *,N ! Perform the network I/O WRITE (UNIT=10, IOSTAT=IOS, ERR=900) N READ (UNIT=10, IOSTAT=IOS, ERR=900) N ! Display the number and process errors PRINT 102, N 102 FORMAT (' The new value is ',I11) GO TO 999 900 PRINT *, 'Unexpected I/O Error Number ', IOS 999 CLOSE (UNIT=10) END PROGRAM |
The task file REMOTE.COM on the remote node contains the following OpenVMS DCL commands:
$ DEFINE SYS$PRINT NL: ! Inhibit printing of log $ RUN DB0:[NET]REMOTE.EXE ! Run remote program $ PURGE/KEEP=2 REMOTE.LOG ! Delete old log files |
The remote program PARIS::DB0:[NET]REMOTE.EXE contains the following source code:
OPEN (UNIT=10, FILE='SYS$NET', FORM='UNFORMATTED', & ACCESS='SEQUENTIAL', STATUS='OLD') READ (UNIT=10) N N = N + 1 WRITE (UNIT=10) N CLOSE (UNIT=10) END PROGRAM |
On using DECnet, refer to the DECnet for OpenVMS Networking Manual and DECnet for OpenVMS Guide to Networking.
An exception condition, as the term is used in this chapter, is an event, usually an error, that occurs during the execution of a program and is detected by system hardware or software or by logic in a user application program. To resolve exception conditions, you can create a condition-handler routine.
This chapter addresses error handling only as it relates to the creation and use of condition-handler routines. Condition-handler routines are specific to the OpenVMS operating system. For a general discussion of error handling, see Chapter 7.
Examples of the types of exception conditions detected by system hardware and software are:
When an exception condition is detected by system hardware or software or by your program, that condition is signaled (by means of a signal call) to the OpenVMS Condition-Handling Facility (CHF). The CHF then invokes one or more condition-handler routines that will attempt to either resolve the condition or terminate the processing in an orderly fashion.
The CHF allows a main program and each subprogram that follows it, regardless of call depth, to establish a condition-handler routine (one per program unit). Each of these condition-handler routines can potentially handle any or all software or hardware events that are treated as exception conditions by the user program or by the system hardware or software. More than one condition handler for a given condition can be established by different program units in the call stack (see the HP OpenVMS Programming Concepts Manual).
The address of the condition handler for a particular program unit is placed in the call frame for that unit in the run-time call stack.
When the program unit returns to its caller, the call frame is removed and the condition handler for that program unit can no longer be accessed by the CHF. Multiple condition handlers can be accessed by the CHF in the processing of a single exception condition signal. A process-wide handler can be established using the SYS$SETEXV system service.
Throughout this chapter, the term program unit refers to an executable Fortran main program, subroutine, or function.
The Condition-Handling Facility (CHF) receives control and coordinates processing of all exception conditions that are signaled to it. The signals are issued under the following circumstances:
In cases where the default condition handling is insufficient (see Section 14.3), you can develop your own handler routines and use the HP Fortran intrinsic function LIB$ESTABLISH to identify your handlers to the CHF. Typically, your needs for special condition handling are limited to the following types of operations:
When an exception condition is detected by a system hardware or software component or by a component in the user application program, the component calls the CHF by means of a signal routine (LIB$SIGNAL or LIB$STOP), passing a value to the CHF that identifies the condition. The CHF takes program control away from the routine that is currently executing and begins searching for a condition-handler routine to call. If it finds one, it establishes a call frame on the run-time call stack and then invokes the handler. The handler routine then attempts to deal with the condition.
The sections that follow describe the CHF in detail---how it operates, how user programs can interact with it, and how users can code their own condition-handling routines:
When the system creates an HP Fortran user process, it establishes a system-defined condition handler that will be invoked by the CHF under the following circumstances:
When establishing the default handler, the system has two handlers to choose from: the traceback handler and the catchall handler.
The /DEBUG and /TRACEBACK qualifiers---on the FORTRAN and LINK command lines, respectively---determine which default handler is enabled. If you take the defaults for these qualifiers, the traceback handler is established as the default handler. To establish the catchall handler as the default, specify /NODEBUG or /DEBUG=NOTRACEBACK on the FORTRAN command line and /NOTRACEBACK on the LINK command line.
Use the FORTRAN command /SYNCHRONOUS_EXCEPTIONS (Alpha only) qualifier to ensure precise exception reporting.
User-program interactions with the CHF are strictly optional and application-dependent. In each program unit, you have the option of establishing (and removing) a single condition handler to handle exceptions that may occur in that program unit or in subsequent subprograms (regardless of call depth). Once a program unit returns to its caller, its call frame is removed and any condition handler that the program unit has established becomes inaccessible.
The condition handler established by the user program can be coded to handle an exception condition signaled either by system hardware, a HP Fortran system software component, or the user program itself. User-program signals are issued by means of the LIB$STOP and LIB$SIGNAL routines described in Section 14.4.2.
Although condition handlers offer a convenient and structured approach to handling exception conditions, they can have a significant impact on run-time performance when a condition handler is actually used. For commonly occurring application-specific conditions within a loop, for example, it may be wise to use other methods of dealing with the conditions. The best use of the facility is in large applications in which occasional exception conditions requiring special handling are anticipated.
The following sections describe how to establish and remove condition handlers and how to signal exception conditions.
Previous | Next | Contents | Index |