davidsen@steinmetz.ge.com (William E. Davidsen Jr) (07/26/88)
I have a problem which requires running a number of similar programs, then a final program. It's not a make, but the solution might be applied there, too. I want to start up to N tasks, and when I try to start the N+1th task I want to hang until at least one is done. I want to do this in a portable way which will run of reasonable BSD and USG systems. I have a hack which more of less works under SysV using semiphores and stuff, but it's not portable, and a real kludge. If someone can give me a clue on a better way I'd be grateful. -- bill davidsen (wedu@ge-crd.arpa) {uunet | philabs | seismo}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me
kjk@pbhyf.PacBell.COM (Ken Keirnan) (07/27/88)
In article <11658@steinmetz.ge.com> davidsen@crdos1.UUCP (bill davidsen) writes: > > I have a problem which requires running a number of similar programs, >then a final program. It's not a make, but the solution might be applied >there, too. > > I want to start up to N tasks, and when I try to start the N+1th task >I want to hang until at least one is done. I want to do this in a >portable way which will run of reasonable BSD and USG systems. > > I have a hack which more of less works under SysV using semiphores and >stuff, but it's not portable, and a real kludge. If someone can give me >a clue on a better way I'd be grateful. A relatively easy way to accomplish this similar to the way "init" works. Keep a table of the process IDs for each child process as it is created, then perform a "wait()". When wait returns, check the return value for fail (no children to wait for) and then with each value in the table. If the return value is "fail", or a match is found in the table, drop through and execute the final child process. If you need to wait on all children prior to executing the final process, keeping track of the children is not necessary. In this case simply loop until wait() returns error status. Ken Keirnan -- Ken Keirnan - Pacific Bell - {att,bellcore,sun,ames,pyramid}!pacbell!pbhyf!kjk San Ramon, California kjk@pbhyf.PacBell.COM
les@chinet.chi.il.us (Leslie Mikesell) (07/28/88)
In article <11658@steinmetz.ge.com> davidsen@crdos1.UUCP (bill davidsen) writes: > > I want to start up to N tasks, and when I try to start the N+1th task >I want to hang until at least one is done. I want to do this in a >portable way which will run of reasonable BSD and USG systems. > You didn't say if the tasks all start from the same parent or if the child processes can start new tasks also. If one parent starts all the processes, it should be able to just count them. Set up a signal handler for SIGCLD which does a wait() and decrements the process count, then re-enables the handler. If you reach the maximum tasks, just pause(). This should work at least in sysV, and unlike other signals, you should never miss a SIGCLD. If the child processes are allowed to fork() also, it becomes more complicated and you would need some form of IPC, perhaps a pipe inherited from the original parent. The child could write its PID down the pipe and wait for a signal before each fork(). Les Mikesell
davidsen@steinmetz.ge.com (William E. Davidsen Jr) (07/29/88)
In article <11658@steinmetz.ge.com> I write: | | I have a problem which requires running a number of similar programs, | then a final program. It's not a make, but the solution might be applied | there, too. Well about 30 people have written to say that all I do is keep a PID table, so I guess I didn't clarify the question very well. What I need to do is something like the 'batch' command, in that the commands to be run will not be started by the same processes, at least on its own. I need to be able to handle a number of commands, possibly from a number of other programs, in a portable way. On SysV I have a kludge which reads a named pipe and when it gets a command it either starts a process to execute it or waits for an existing process to complete. I never worked on getting the status back to the submitter, because I don't seem to find named pipes on all (or even most) BSD systems. What I have now is more or less a daemon to run jobs, although I would be willing to implement almost anything which will work. I certainly don't mind having some code which is used for BSD and some for SysV, but I don't want to use non-portable features and have every few lines be more stuff in an ifdef. Here's one way to use it: for file in *.mu do runsome -3 ioproc $file # ^^^^^^^ A ^^^^^^^^^^^^^^^^ # what I need | the command # max to run done runwait ^^^^^^^ # wait for all to stop It could also go in a make file: # compile three at a time .c.o: runsome -3 $(CC) $< -c prog: $(OBJFILES) runwait cc $(LFLAGS) $(OBJFILES) -o prog what I have now is more or less: pipename=`runsome 3` # run just three for file in *.c do echo "indent ${file}" > ${pipename} done runwait ${pipename} Thanks again to all who responded, I mailed thanks to all but some bounced, and hopefully this time I have explained better. -- bill davidsen (wedu@ge-crd.arpa) {uunet | philabs | seismo}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me