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 + -
显示快捷键?