📄 p4.txt
字号:
int myid, size, nprocs, from, i, type; myid = p4_get_my_id(); nprocs = p4_num_total_ids(); for (i=0; i < nprocs; i++) { if (i != myid) p4_send(100, i, msg, strlen(msg)+1); } for (i=0; i < nprocs - 1; i++) { type = -1; from = -1; incoming = NULL; p4_recv(&type,&from,&incoming,&size); printf("%d received msg=:%s: from %d",myid,incoming,from); p4_msg_free(incoming); } } This program demonstrates several features of p4's support formessage-passing. Before we get into the specifics however, let's examinethe overall logic of the program. Each process determines its own id andthe total number of processes executing in this run (including process 0).Then, in the first for-loop, each process sends a single message to each ofthe other processes. Finally, in the second for-loop, each process receivesa message from each of the other processes. The p4_send call requires 4 arguments: o a message type (arbitrarily chosen to be 100 here) o the id of the process to receive the message o the message itself o the size of the message The use of p4_recv is slightly more complicated. First, we assign -1 toeach of the parameters type and from. This is done because -1represents a wildcard value indicating we are willing to receive a messageof any type from any process. Here, we could have coded type to be 100,and specified from equal to the value of i each time through the loop(skipping our own id). By setting incoming to NULL, we have alsoindicated to p4_recv that we do not have a buffer in which to place thereceived message, so p4_recv should obtain a buffer for us and placethe message in that buffer. p4_recv treats these three parameters asboth input and output values. Thus, it alters the value of each such that type and from indicate the type of message received and the id of theprocess that sent it. The value of incoming is altered to point to thebuffer where the message was placed. The size parameter is strictly anoutput parameter and indicates the size of the received message. It ispossible for the user to provide his own buffer; this will be demonstratedlater. Finally, note that p4_msg_free frees the message buffer obtained by p4_recv. The procedure p4_msg_free should be called only afterthe contents of the message are no longer needed. P4_msg_free shouldbe used to free these buffers because, although a user only sees the dataportion of a message, p4 internally represents a message as a structureddata item. To compile and link this program for execution, you need to create amakefile. We will assume that you have installed p4 in /usr/local/p4 andthat you have typed the program above into a file name p4simple.c in thedirectory /home/mylogin/p4pgms. To build your makefile, copy the file /usr/local/p4/messages/makefile.proto into your working directory. This is a prototype makefile that containsmachine-independent information, and which p4 can use to build amachine-specific makefile for your program. This prototype makefilecontains information about several sample programs that demonstratemessage-passing in p4. If you edit this file, you will see information formaking a program named sr_test. Do a global change of sr_test top4simple. You should also change the value of P4_HOME_DIR. Itshould contain the full pathname of the p4 system, e.g. /usr/local/p4. Nowchange directories to /usr/local/p4 and type: make makefiles P4ARCH=<machine_type> DIRS=/home/mylogin/p4pgms where <machine_type> is the machine type that you specified whenyou installed p4 on your machine. Now, you should be able to changeback to your directory and see a file named Makefile there. You shouldthen be able to type: make p4simple There is one last piece missing before you can execute your program.Recall that p4_create_procgroup needs to know how manyprocesses to start and where to start them; it reads a file (called a procgroup file) to gather this information. P4 always assumes that youhave a master process, and that you describe the slave processes (processgroups) in the procgroup file. You can name a procgroup file any nameyou choose, but <progname>.pg is the default name. For example, inthis case your procgroup file should be named p4simple.pg. Theinformation contained in procgroup files can get fairly involved, but ifyou have a computer that supports shared memory among processes, thenyou can code a very simple example at first. Let us suppose first that you want to run your program on a network ofworkstations. Then your procgroup should look something like: local O some.network.machine 1 /home/me/p4progs/p4simple This file indicates that you wish to run only the master on the localmachine (the one you are logged into when you execute the program) andone slave on the machine some.network.machine. Now, all you have to do to run your program is type: p4simple You should see a line printed each time a process receives a message fromanother process (on some machines, there may be a restriction that onlyone process can do I/O, however such restrictions are not common).Experiment by changing the number of slaves indicated in the procgroupfile. You may notice that even a small p4 program becomes large when linkedwith the p4 library. You might consider using strip to reduce the sizeor removing -g from the CFLAGS in the makefile. Command-Line Arguments**********************The command-line arguments to a p4 program are all optional. -p4help get this information, then exit -p4pg <file> set procgroup file -p4dbg <level> set debug level -p4rdbg <level> set remote debug level -p4gm <size> set global memory size -p4dmn <domain> provide local domain name -p4out <file> set output file for master -p4rout <file> set output file prefix for remote masters -p4ssport <port#> set private port number for secure server -p4norem don't start remote processes -p4log enable internal p4 logging by alog -p4version print current p4 version number In version 1.4, these flag names are valid without their p4 prefix, forbackward compatibility. If one specifies -p4norem on the command line, p4 will not actuallystart the processes. The master process prints a message suggesting howthe user can do it. The point of this option is to enable the user to start theremote processes under his favorite debugger, for instance. The optiononly makes sense when processes are being started remotely, such as on aworkstation network. The p4 Function Library***********************Overview of the Library=======================In the following sections, we provide details for each p4 function in thelibrary. The procedures are gathered into the following groups: o Functions for managing processes and clusters o Functions for message passing o Functions for shared memory o Functions for timing p4 programs o Functions for debugging p4 programs o Miscellaneous functions o Fortran interface functions Return Codes from p4 Functions==============================Most p4 functions return -1 if an error occurs. Some, however, call thefunction p4_error when severe errors occur. This function prints amessage and then attempts to terminate all of the user's processes Seesection Functions for Debugging p4 Programs. p4 Functions for Managing Processes and***************************************Clusters********In some situations a p4 procedure will give an error message and thenexit. This is typically done as a result of a failed system call and handledby calling the p4 procedure named p4_error that examines the returnvalues from socket procedures, etc. Most of the time however, theprocedures simply return a value. Some of the procedures return no valueand thus are declared to return VOID. Some of the procedures returneither a pointer to a character string or NULL; NULL indicates an error.The remaining procedures return an integer value; (-1) indicates an error. Functions for Process Management================================In this section we describe the p4 functions needed for basic creation andtermination of processes. int p4_initenv(argc,argv) int *argc; char **argv; should be called by your program before an attempt is made to use any p4procedures or data areas. We suggest making it the first executablestatement in your program. p4_initenv parses the command linearguments and extracts the ones intended for p4 ignoring all others (seethe discussion of command line arguments). Note that you pass theaddress of argc to p4_initenv so that it can actually remove its ownarguments before your program looks at them. int p4_create(fxn) int (*fxn)(); int p4_create_procgroup() There are two procedures that you can use to create processes in p4, p4_create_procgroup and p4_create. Processes created via p4_create are said to be ``user-managed'' whereas those created by p4_create_procgroup are ``p4-managed''. The p4-managedprocesses are automatically assigned unique id's (beginning with 0 for thebig master), they have message queues allocated for them so that they cando message-passing, and they are able to run either on a shared-memorymultiprocessor with the creating process or they can run on a separatemachine. Processes created via p4_create do not have any of theseadvantages. They must develop their own id's, they cannot domessage-passing, and they can only run on a shared-memorymultiprocessor with the creating process. The only disadvantage of p4_create_procgroup is that you must build a procgroup filedescribing the set of required slave processes before the master programbegins execution. This eliminates the possibility of determining late inthe execution exactly how many processes you want to use to solve aproblem. Generally, this is not a problem, especially since we cancombine p4_create_procgroup and p4_create in the followingway: You can use p4_create_procgroup to develop a network ofprocesses that talk to each other via messages. Each of those processes cancreate further processes to help it out as necessary. The original set ofprocesses communicate with their local slaves through shared data areasand with each other via message-passing. p4_create receives one argument that is a pointer to a function. Itcreates a single new process that executes the indicated function. The newprocess may share data areas (in shared memory) with the parent process.However, the new process is not managed by the p4 system in the sensethat it is not assigned an id, it cannot pass messages, etc. The only p4procedure that deals with user-managed slaves is p4_create. No otherprocedures are even aware of their existence. p4_create_procgroup reads your procgroup file to determine thenumber of slave processes to create and where they are to be placed. Itlooks first for the file specified on the command line following the -p4pg argument if there is one. If there is no such argument, it looks fora file with the same name as the executable (master) file, with the .pgsuffix. If it does not find one, it looks for a file named procgroup. Itbuilds a procgroup table that describes all created processes and gives acopy of the table to each process. The processes then use the table todiscover how to communicate with each other (processes in a cluster cansend messages directly through shared memory or some othervendor-specific mechanism), others communicate via sockets). Analternative method is to build the table in memory yourself and use p4_startup. The effect of p4_create_procgroup can be obtained in anotherway if a system would prefer to use its own way of specifying thelocations of processes. A user may allocate the procgroup data structureand then fill it in ``by hand'' rather than by reading a file in p4 procgroupformat. The following procedures support this method of startingprocesses. struct p4_procgroup *p4_alloc_procgroup() allocates a procgroup data structure of the form described in p4.h. Theformats of individual entries (p4_procgroup_entry) are given thereas well. int p4_startup(pg) struct p4_procgroup *pg; starts processes as specified by an an already-created procgroup datastructure allocated by p4_alloc_procgroup and filled in by the userusing the structures p4_procgroup_entry and p4_procgroup. VOID p4_wait_for_end() is the p4 termination/cleanup procedure that you should invoke at the endof every execution of a program that uses p4. For the master process, itdoes some termination processing and then waits for slave processes toend. It should be called by all processes. int p4_get_my_id() returns an integer value representing the id of the process assigned by thep4 system. If the process is not a p4-managed process, the value (-1) isreturned. int p4_num_total_ids() returns an integer value indicating the total number of ids started by p4 inall clusters, including the big master and all remote masters. int p4_num_total_slaves() returns an integer value indicating the total number of processes startedby p4 in all clusters, including all remote masters but not the big master. Functions for Cluster Management================================The p4 system supports the cluster model of parallel computation, inwhich subsets of processes share memory with one another, with theclusters communicating via messages. A procgroup file for a programwritten for the cluster model might look like this: local 4 alliant1.abc.edu 5 /home/me/myprog alliant2.abc.edu 5 /home/me/myprog encore.somewhere.edu 5 /usrs/me/myprog This would specify a total of 20 processes, 5 (including the master)running on the local machine (here assumed to be capable of supportingfive processes that share memory) together with 5 slaves each on threeother shared-memory machines. One process out of each set of remoteslaves will be the ``remote master'' for that cluster.. VOID p4_get_cluster_ids(start,end) int *start; int *end; receives pointers to two integers. It places the p4-assigned id's of the firstand last id's within the current cluster into the two arguments (includingthe remote master). int p4_get_my_cluster_id() returns a unique id (relative to 0) within a cluster of p4-managedprocesses. Thus, a cluster master will always have a cluster id of 0. It isnot clear that a separate cluster id is really useful, but the functionality isprovided just in case. BOOL p4_am_i_cluster_master() returns a BOOL value indicating whether the invoking process is the``cluster master'' process within its cluster. int p4_num_cluster_ids() returns an integer value indicating the number of ids in the current clusteras started by p4_create_procgroup.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -