#include "stdafx.h" #include #include #include static int __nloop = 2; static int __delay = 10; static acl::atomic_long __producing = 0; static acl::atomic_long __consuming = 0; class producer : public acl::thread { public: producer(acl::fiber_event& event, acl::fiber_cond& cond) : event_(event) , cond_(cond) { this->set_detachable(false); } private: ~producer(void) {} private: acl::fiber_event& event_; acl::fiber_cond& cond_; // @override void* run(void) { for (int i = 0; i < __nloop; i++) { if (__delay > 0) { acl_doze(__delay); } printf(">> producer(%ld): lock\r\n", this->self()); assert(event_.wait()); printf(">> producer(%ld): notify\r\n", this->self()); assert(cond_.notify()); printf(">> producer(%ld): unlock\r\n", this->self()); assert(event_.notify()); __producing++; } return NULL; } }; class consumer : public acl::thread { public: consumer(acl::fiber_event& event, acl::fiber_cond& cond, long long timeout) : event_(event) , cond_(cond) , timeout_(timeout) { this->set_detachable(false); } private: ~consumer(void) {} private: acl::fiber_event& event_; acl::fiber_cond& cond_; long long timeout_; void* run(void) { printf("<< consumer: lock\r\n"); assert(event_.wait()); for (int i = 0; i < __nloop; i++) { printf("<< consumer(%ld): wait\r\n", this->self()); if (cond_.wait(event_, timeout_) == false) { printf("<< consumer: wait %s\r\n", acl::fiber::last_serror()); break; } printf("<< consumer(%ld): wakeup\r\n", this->self()); __consuming++; } return NULL; } }; ////////////////////////////////////////////////////////////////////////////// static void usage(const char* procname) { printf("usage: %s -h [help]\r\n" " -t nthreads[default: 2]\r\n" " -n nloop[default: 2]\r\n" " -d delay[default: 0 ms]\r\n" " -t wait_timeout[default: -1]\r\n" , procname); } int main(int argc, char *argv[]) { int ch, nproducer = 1, nconsumer = 1, timeout = -1; bool use_mutex = false; acl::acl_cpp_init(); acl::log::stdout_open(true); while ((ch = getopt(argc, argv, "hp:c:n:d:mt:")) > 0) { switch (ch) { case 'h': usage(argv[0]); return 0; case 'p': nproducer = atoi(optarg); break; case 'c': nconsumer = atoi(optarg); break; case 'n': __nloop = atoi(optarg); break; case 'd': __delay = atoi(optarg); break; case 'm': use_mutex = true; break; case 't': timeout = atoi(optarg); break; default: break; } } acl::log::stdout_open(true); acl::fiber::stdout_open(true); acl::fiber_event event(use_mutex); acl::fiber_cond cond; std::vector threads; for (int i = 0; i < nconsumer; i++) { acl::thread* thr = new consumer(event, cond, timeout); threads.push_back(thr); thr->start(); } for (int i = 0; i < nproducer; i++) { acl::thread* thr = new producer(event, cond); threads.push_back(thr); thr->start(); } for (std::vector::iterator it = threads.begin(); it != threads.end(); ++it) { (*it)->wait(); delete *it; } printf("all over, nloop=%d, producing=%lld, consuming=%lld\r\n", __nloop, __producing.value(), __consuming.value()); return 0; }