ptypes_test.cxx
来自「PTypes是一个扩充了多线程和网络功能的STL库」· CXX 代码 · 共 1,615 行 · 第 1/3 页
CXX
1,615 行
f->get(); f->putback(); pout.putf("%s", pconst(f->token(cset("~20-~FF")))); f->preview(); if (f->get_eol()) { f->skipline(); pout.put("\n"); } if (f->get_eof()) pout.put("EOF\n");// f.error(1, "Test error message");}void mem_test(){ pout.put("\n--- OUT/IN MEMORY CLASS\n"); { outmemory m(12, 5); m.open(); m.put("MEMOry"); m.put(" c"); m.put("lass is working"); m.seek(1); m.put("emo"); showstr("Memory class", m.get_strdata()); // try reuse m.open(); m.put("memory"); showstr("memory", m.get_strdata()); } { inmemory m(""); m.open(); showstr("", m.token("*")); m.set_strdata("gArbaGe"); m.open(); // try reuse m.set_strdata("string strong"); m.set_bufsize(2); // has no effect m.open(); showstr("string", m.token("a-z")); m.seek(-6, IO_END); showstr("strong", m.token("a-z")); }}#ifndef PTYPES_ST//// multithreading////// rwlock test//const int rw_max_threads = 30;const int rw_max_tries = 30;const int rw_max_delay = 20;const int rw_rw_ratio = 5;const bool rw_swap = false;class rwthread: public thread{protected: virtual void execute();public: rwthread(): thread(false) {} virtual ~rwthread() { waitfor(); }};rwlock rw;int reader_cnt = 0;int writer_cnt = 0;int total_writers = 0;int total_readers = 0;int max_readers = 0;int prand(int max){ return rand() % max;}void rwthread::execute(){ for(int i = 0; i < rw_max_tries; i++) { psleep(prand(rw_max_delay)); bool writer = prand(rw_rw_ratio) == 0; if (writer ^ rw_swap) { rw.wrlock(); pout.put('w'); if (pincrement(&writer_cnt) > 1) fatal(0xa0, "Writer: Huh?! Writers in here?"); pincrement(&total_writers); } else { rw.rdlock(); pout.put('.'); int t; if ((t = pincrement(&reader_cnt)) > max_readers) max_readers = t; if (writer_cnt > 0) fatal(0xa1, "Reader: Huh?! Writers in here?"); pincrement(&total_readers); } psleep(prand(rw_max_delay)); if (writer ^ rw_swap) pdecrement(&writer_cnt); else pdecrement(&reader_cnt); rw.unlock(); }}void rwlock_test(){// #ifdef __PTYPES_RWLOCK__ pout.put("\n--- RWLOCK\n"); rwthread* threads[rw_max_threads]; srand((unsigned)time(0)); int i; for(i = 0; i < rw_max_threads; i++) { threads[i] = new rwthread(); threads[i]->start(); } for(i = 0; i < rw_max_threads; i++) delete threads[i]; pout.putf("\nmax readers: %d\n", max_readers); pout.putline("do writers 'starve'?");// #endif}//// jobqueue test ----------------------------------------------------------//const int MSG_MYJOB = MSG_USER + 1;const int NUM_JOB_THREADS = 3;class jobthread: public thread{protected: int id; jobqueue* jq; virtual void execute();public: jobthread(int iid, jobqueue* ijq): thread(false), id(iid), jq(ijq) {} ~jobthread() { waitfor(); }};void jobthread::execute(){ bool quit = false; while (!quit) { message* m = jq->getmessage(); try { switch (m->id) { case MSG_MYJOB: // ... do the job ... psleep(prand(10)); // report pout.putf("Thread %d finished the job (param=%d)\n", id, m->param); break; case MSG_QUIT: quit = true; break; } } catch(...) { // the message object must be freed! delete m; throw; } delete m; }}void jobqueue_test(){ pout.put("\n--- JOBQUEUE\n"); jobqueue jq(3); tobjlist<jobthread> threads(true); srand((unsigned)time(0)); // create the thread pool and start all threads int i; for(i = 0; i < NUM_JOB_THREADS; i++) { jobthread* j = new jobthread(i + 1, &jq); j->start(); threads.add(j); } // post jobs for processing jq.post(MSG_MYJOB, 1); jq.post(MSG_MYJOB, 2); jq.post(MSG_MYJOB, 3); jq.post(MSG_MYJOB, 4); jq.post(MSG_MYJOB, 5); jq.post(MSG_MYJOB, 6); jq.post(MSG_MYJOB, 7); jq.post(MSG_MYJOB, 8); // terminate all threads for(i = 0; i < NUM_JOB_THREADS; i++) jq.post(MSG_QUIT); // threads are being waitfor()'ed and destroyed // automatically by the list object}//// msgqueue test ----------------------------------------------------------//const int MSG_DIAG = MSG_USER + 1;//// msgqueue test////// class diagmessage//class diagmessage: public message{protected: string module; string diagstr; friend class diagthread;public: diagmessage(string imodule, string idiagstr) : message(MSG_DIAG), module(imodule), diagstr(idiagstr) {}};//// class diagthread//class diagthread: public thread, protected msgqueue{protected: virtual void execute(); // override thread::execute() virtual void cleanup(); // override thread::cleanup() virtual void msghandler(message& msg); // override msgqueue::msghandler()public: diagthread(): thread(false), msgqueue() { } void postdiag(string module, string diagstr); void postquit();};void diagthread::postdiag(string module, string diagstr){ msgqueue::post(new diagmessage(module, diagstr));}void diagthread::postquit(){ msgqueue::post(MSG_QUIT); }void diagthread::execute(){ // starts message queue processing; calls // msghandler for each message msgqueue::run();}void diagthread::cleanup(){}void diagthread::msghandler(message& msg){ switch (msg.id) { case MSG_DIAG: { diagmessage& m = (diagmessage&)msg; pout.putf("%s: %s\n", pconst(m.module), pconst(m.diagstr)); } break; default: defhandler(msg); }}//// class testthread//class testthread: public thread{protected: diagthread* diag; string myname; virtual void execute(); virtual void cleanup();public: semaphore sem; timedsem tsem; testthread(diagthread* idiag) : thread(false), diag(idiag), myname("testthread"), sem(0), tsem(0) {}};void testthread::execute(){ diag->postdiag(myname, "starts and enters sleep for 1 second"); psleep(1000); diag->postdiag(myname, "signals the timed semaphore"); tsem.post(); diag->postdiag(myname, "releases the simple semaphore"); sem.post(); diag->postdiag(myname, "enters sleep for 1 more second"); psleep(1000);}void testthread::cleanup(){ diag->postdiag(myname, "terminates");}int thread_test(){ pout.put("\n--- THREAD AND SEMAPHORE CLASSES\n"); int v = 0; showint(0, pexchange(&v, 5)); showint(5, pexchange(&v, 10)); showint(11, pincrement(&v)); showint(10, pdecrement(&v)); diagthread diag; testthread thr(&diag); string myname = "main"; diag.start(); thr.start(); diag.postdiag(myname, "waits 5 secs for the timed semaphore (actually wakes up after a second)"); thr.tsem.wait(5000); // must exit after 1 second instead of 5 diag.postdiag(myname, "waits for the semaphore"); thr.sem.wait(); diag.postdiag(myname, "now waits for testthread to terminate"); thr.waitfor(); diag.postquit(); diag.waitfor(); return 0;}//// trigger test//class trigthread: public thread{protected: diagthread* diag; string myname; virtual void execute();public: trigger trig; trigthread(diagthread* idiag) : thread(false), diag(idiag), myname("trigthread"), trig(true, false) {} virtual ~trigthread() { waitfor(); }};void trigthread::execute(){ diag->postdiag(myname, "waits on the trigger"); trig.wait(); psleep(2000); diag->postdiag(myname, "waits on the trigger"); trig.wait(); diag->postdiag(myname, "terminates");}int trigger_test(){ pout.put("\n--- TRIGGER\n"); diagthread diag; trigthread thr(&diag); string myname = "main"; diag.start(); thr.start(); psleep(1000); diag.postdiag(myname, "posts the trigger"); thr.trig.post(); psleep(1000); diag.postdiag(myname, "posts the trigger again"); thr.trig.post(); thr.waitfor(); diag.postquit(); diag.waitfor(); return 0;}#endif // PTYPES_ST//// md5 test//static md5_digest digest;char* md5str(string data){ outmd5 m; m.open(); m.put(data); memcpy(digest, m.get_bindigest(), sizeof(md5_digest)); return (char*)digest;}string cryptpw(string username, string password){ outmd5 m; m.open(); m.put(username); m.put(password); m.close(); return m.get_digest();}void md5_test(){ pout.put("\n--- MD5 OUTPUT STREAM\n"); // MD5 test suite from RFC1321 showhex("d41d8cd98f00b204e9800998ecf8427e", md5str(""), md5_digsize); showhex("0cc175b9c0f1b6a831c399e269772661", md5str("a"), md5_digsize); showhex("900150983cd24fb0d6963f7d28e17f72", md5str("abc"), md5_digsize); showhex("f96b697d7cb7938d525a2f31aaf161d0", md5str("message digest"), md5_digsize); showhex("c3fcd3d76192e4007dfb496cca67e13b", md5str("abcdefghijklmnopqrstuvwxyz"), md5_digsize); showhex("d174ab98d277d9f5a5611c2c9f419d9f", md5str("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), md5_digsize); showhex("57edf4a22be3c955ac49da2e2107b67a", md5str("12345678901234567890123456789012345678901234567890123456789012345678901234567890"), md5_digsize); showstr("t0htL.C9vunX8SPPsJjDmk", cryptpw("hovik", "myfavoritelonglonglongpassword"));}//// outstm::putf() test//void putf_test(){ pout.put("\n--- PUTF TEST\n"); outmemory m; m.open(); m.putf("%s, %c, %d, %llx", "string", 'A', 1234, large(-1)); showstr("string, A, 1234, ffffffffffffffff", string(m.get_data(), m.tell())); m.open(); m.putf(" %%, %#o, %+010d", 0765, -3); showstr(" %, 0765, -000000003", string(m.get_data(), m.tell()));}//// pinet/socket tests//void inet_test1(){ try { pout.put("\n--- INET SOCKET & UTILITIES\n");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?