[wiki:WikiStart Orbit] > [wiki:Documentation/OTG OTG] > [wiki:Documentation/OTG/FuncSpec Function Specifications] > Understanding OTG Main Program Tha main() fucntion in [source:otg/trunk/src/cpp/otg.cpp#latest otg.cpp] is given as below: {{{ int main(int argc, const char * argv[]) { OrbitApp *otg1 = new OTGApp(); try { pthread_t thread1; char *protocol_name = "udp"; char *generator_name = "cbr"; char *debuglog_name = NULL; parseOptionsPhase1(argc, argv, &protocol_name, &generator_name, &debuglog_name); Port* port = createPort(protocol_name); Generator *gen = createGenerator(generator_name); otg1->init(&argc, argv, debuglog_name); //Initialize OML parseOptionsPhase2(argc, argv, port, gen); port->init(); gen->init(); Stream *str = new Stream(0, gen, port, otg1); //default stream No.0 int cst1 = pthread_create( &thread1, NULL, create_stream_function, (void *)str); if (cst1!=0)throw "Create a Stream Thread Failed..."; work(str); //this is the main thread } catch (const char *reason ) { cerr << "Exception:" << reason << endl; exit(-1); } return 0; } }}} === Explanation === As can be seen, this is a very clean and short program. I explain it in detail. 1. First an [source:otg/trunk/src/cpp/orbitappt.h#latest OrbitApp] object is createdd to handle all OML-related stuff. 1. Parsing user command-line input to determine 1. protocol type 1. generator type 1. debug mode is used or not. and if yes, the log file path. 1. Create [source:otg/trunk/src/cpp/port.h#latest Port] and [source:otg/trunk/src/cpp/generator.h#latest Generator] based on the "protocol type" and "generator type" 1. Init the OML-related object. 1. Conduct 2nd-tier parse to get all detail parameters of Port and Generator 1. Init Port and Generator 1. Create Stream Object to control Port and Generator, as a separate thread. 1. Let work() acting as the continuing main thread to handle run-time user inputs. this function is designed as an eternal while loop. === Discussion === We are going to have multiple streams in one OTG using multiple thread. The main thread is handling command-line inputs. Each stream is a separate thread, by calling the stream_init function, the stream is independently sending packets. Now, one stream is enough. Although the current architecture allows more streams in more threads (and we already test this successfully), there seems no need for doing this. If multiple streams are preferred, the user could run multiple OTG programs.