This type of custom server can be used to improve the throughput of the single-process blocking model. It is suitable for custom servers whose user functions are self-sufficient, that is, they do not need any data to persist between invocations. It handles a request to completion, but on a dedicated process, so access to the custom server by another channel process is not denied.
There may be a fixed number of child processes, defined at initialization, or a more sophisticated custom server can create or destroy processes based on demand.
The main() process forks the required number of times at initialization. This can be done using a system-generated main function, within the custom server initialization function. The main loop for each of the processes uses CA_Receive_DT_Msg() with the CA_WAIT flag set. If more than one process is waiting for a request in CA_Receive_DT_Msg(), the system supplies the request to one of these processes, which handles it to completion. The other processes continue to wait.
The advantages of a multiprocess non-associated operation design are that:
The disadvantages of a multiprocess non-associated operation design are that:
To create a multi-process non-associated custom server, implement the general design as shown in Example code for a multiprocess custom server, particularly the m_open_link subroutine where the code does a fork to provide many custom server processes. It is necessary to remember to close all the child processes when the custom server is terminated as shown in m_close_link.
For multi-process non-associated Custom Servers, it is insufficient to just use the -DMULTI compile flag to create a multi-process custom server. The code also has to fork children to so there are multiple processes to handle simultaneous custom server requests. The initialization and termination code should resemble the following:
int num_pids; pid_t pid[700]; /* Max Number of PIDs required */ . /* The number of children required is specified as the first arg in the Custom Server Properties window */ void MP_init (int argc, char *argv[]) { int i; int new_pid; pid[0] = getpid(); if (argc < 2) return; num_pids = atoi(argv[1]); for (i = 1; i <= num_pids; i++) { if ((new_pid = fork()) == 0) break; pid[i] = new_pid; printf("Child %d ==> pid %d is started\n", i, new_pid); } return; } void MP_term (void) { int i; if (pid[0] == getpid()) { for (i = 1; i <= num_pids; i++) { if (pid[i] > 0) { kill(pid[i], SIGINT); printf("Child %d ==> pid %d is stopped\n", i, pid[i]); } } } printf("Pid %d is terminating\n", getpid()); return; }