Home Corporate Contacts TETware Knowledgebase |
ProductsSolutionsInformationDatasheetDocumentationFAQKnowledgebase |
Return to Knowledgebase Index20. How to create multiple processes using tet_fork()This information is not applicable to Win32 systems.
Question I have a need to fork multiple process. After forking multiple processes, the parent should wait for all these processes. Typically my code should like this: for (i = 0; i < 10; i++) { if ((pid = fork()) == 0) child_func(); } for (i = 0; i < 10; i++) { waitpid(.......); /* check for the child's return status... */ } . . .
Answer You can do this using recursive calls to a
For example: #include <stdlib.h> #include <tet_api.h> void (*tet_startup)() = TET_NULLFP, (*tet_cleanup)() = TET_NULLFP; static void tp1(), tp1_child(), tp1_parent(); struct tet_testlist tet_testlist[] = { { tp1, 1 }, { TET_NULLFP, 0 } }; static int tp1_fcount; static int testfail; static void tp1() { testfail = 0; tp1_fcount = 0; tp1_parent(); if (!testfail) tet_result(TET_PASS); } static void tp1_parent() { int level; void (*parentproc)(); if ((level = ++tp1_fcount) < 10) parentproc = tp1_parent; else parentproc = TET_NULLFP; (void) tet_printf("about to call tet_fork(): level = %d", level); if (tet_fork(tp1_child, parentproc, 30, 0) < 0) { /* API prints an infoline and generates a result */ testfail++; } else (void) tet_printf("tet_fork() succeeded, level = %d", level); } static void tp1_child() { (void) tet_printf("in child process, PID = %d", getpid()); tet_exit(0); } Question How to I extend this example to an arbitrary number of child processes without creating an infinite number of stack frames? Answer This is a rather different situation. You can call
When this feature is used, the
Then it is your responsibility to make sure that you have waited for
all the child processes to exit before the test purpose returns control
to the TCM.
For example: #include <stdlib.h> #include <errno.h> #include <signal.h> #include <tet_api.h> void (*tet_startup)() = TET_NULLFP, (*tet_cleanup)() = TET_NULLFP; static void tp1(), tp1_child(), tp1_parent(); struct tet_testlist tet_testlist[] = { { tp1, 1 }, { TET_NULLFP, 0 } }; static int testfail; static pid_t child_pid; void tp1() { testfail = 0; for (;;) { /* ** you will need some code here to wait for some event ** and/or break out of the loop */ tet_infoline("parent: about to call tet_fork()"); if (tet_fork(tp1_child, tp1_parent, -1, 0) < 0) { /* API prints a diagnostic */ testfail++; break; } (void) tet_printf("parent: child PID = %d", child_pid); } /* ** you must ensure that all the child processes have exited ** at this point */ if (!testfail) tet_result(TET_PASS); } static void tp1_parent() { int pid; /* create a dummy child for the API to kill */ switch (pid = fork()) { case 0: /* child must not call any API functions */ (void) signal(SIGTERM, SIG_DFL); pause(); _exit(0); break; case -1: /* real trouble here - the only safe thing to do is to exit from the test case */ (void) tet_printf("fork() failed, errno = %d", errno); tet_exit(1); } /* arrange for the API to kill the dummy child instead of the childproc function */ child_pid = tet_child; tet_child = pid; return; } static void tp1_child() { (void) tet_printf("in child process, PID = %d", getpid()); /* whatever you want here */ tet_exit(0); } Not that this example does not contain any code to wait for the child processes, or to cause the main loop to end. So if you compile and run the code as it stands, you will run out of processes at some point.
See also
|