├── .gitignore ├── 1.1.1红黑树 └── main.cpp ├── 1.1.2b树 └── btree.cpp ├── 1.3.1智能指针-move-forward-左右值引用 └── src1-cmake │ ├── 1-1-error-example.cpp │ ├── 1-2-shared_ptr-app.cpp │ ├── 1-3-1-delete.cpp │ ├── 1-3-1-reset-count.cpp │ ├── 1-3-2-cycle-shared-ptr.cpp │ ├── 1-3-2-shared_from_this.cpp │ ├── 1-3-2-shared_from_this2.cpp │ ├── 1-4-unique_ptr-deleter.cpp │ ├── 1-4-unique_ptr.cpp │ ├── 1-5-1-weak_ptr.cpp │ ├── 1-5-4-misuse-weak_ptr.cpp │ ├── 2-1-lr_value.cpp │ ├── 2-1-mystring.cpp │ ├── 2-2-3-1-r-move.cpp │ ├── 2-2-3-2-r-move.cpp │ ├── 2-3-1-memory.cpp │ ├── 2-3-1-memory2.cpp │ ├── 2-3-1-memory3.cpp │ ├── 2-3-2-move.cpp │ ├── 2-3-3-forward1.cpp │ ├── 2-3-3-forward2.cpp │ ├── 2-3-4-emplace_back.cpp │ ├── 2-3-4-emplace_back2.cpp │ ├── 3-lambda.cpp │ ├── 4-priority_queue.cpp │ ├── 4-unordered_map.cpp │ ├── CMakeLists.txt │ ├── time_interval.h │ └── 编译说明.txt ├── 1.3.2C++11多线程thread-互斥量-条件变量-原子变量 ├── 1-2-4-lock.cpp ├── 1-2-4-unique_lock.cpp ├── 1-2-mutex1.cpp ├── 1-2-mutex2-dead-lock.cpp ├── 1-2-recursive_mutex1.cpp ├── 1-2-shared_ptr-mutex-notify.cpp ├── 1-2-timed_mutex.cpp ├── 1-3-condition-sync-queue.cpp ├── 1-3-condition-sync-queue2.cpp ├── 1-4-atomic.cpp ├── 1-5-call_once.cpp ├── 1-5-future.cpp ├── 1-5-package_task.cpp ├── 1-5-promise.cpp ├── 1-thread.cpp ├── 1-thread1-simple.cpp ├── 1-thread2-pack.cpp ├── 2-1-function.cpp ├── 2-2-bind.cpp ├── 3-1-variable-parameter.cpp ├── 3-1-variable-parameter2.cpp ├── 3-1-variable-parameter3.cpp ├── 3-1-variable-parameter4.cpp ├── 4-threadpool.cpp ├── 5-1-exception.cpp ├── 5-3-exception.cpp ├── 5-5-exception_ptr.cpp ├── 5-5-make_exception_ptr.cpp ├── 5-5-nested_exception.cpp ├── CMakeLists.txt ├── simple_sync_queue.h ├── sync_queue.h ├── sync_queue2.h ├── zero_thread.cpp ├── zero_thread.h ├── zero_threadpool.cpp ├── zero_threadpool.h └── 说明.txt ├── 2.1.1select poll epoll ├── epoll_initial.c ├── poll.cpp └── select.cpp ├── 2.1.2reactor ├── epoll_reactor_mulcb.c └── epoll_reactor_singecb.c ├── 2.1.3http └── httpserver.c ├── 2.1.4websocket └── websocket_reactor.c ├── 2.2.1C1000K ├── C1000Kclient.c └── C1000Kserver.c ├── 2.3.1NtyCo ├── .gitignore ├── CMakeLists.txt ├── Makefile ├── core │ ├── CMakeLists.txt │ ├── Makefile │ ├── nty_coroutine.c │ ├── nty_coroutine.h │ ├── nty_epoll.c │ ├── nty_queue.h │ ├── nty_schedule.c │ ├── nty_socket.c │ └── nty_tree.h └── sample │ ├── CMakeLists.txt │ ├── Makefile │ ├── mul_port_client_epoll.c │ ├── nty_client.c │ └── nty_server.c ├── 2.4.1udp icmp arp └── udp_icmp_arp.c ├── 3.1.1线程池threadpoll └── threadpoll.c ├── 3.1.2内存池mempoll └── mempoll.c ├── 3.1.3异步请求池asyncpoll ├── async_dns_client_noblock.c └── sync_dns_client.c ├── 3.1.4连接池connpoll ├── CMakeLists.txt ├── DBPool.cpp ├── DBpool.h ├── IMUser.cpp ├── IMUser.h ├── README.md ├── ZeroThreadpool.cpp ├── ZeroThreadpool.h ├── build │ ├── CMakeCache.txt │ ├── CMakeFiles │ │ ├── 3.21.3 │ │ │ ├── CMakeCCompiler.cmake │ │ │ ├── CMakeCXXCompiler.cmake │ │ │ ├── CMakeDetermineCompilerABI_C.bin │ │ │ ├── CMakeDetermineCompilerABI_CXX.bin │ │ │ ├── CMakeSystem.cmake │ │ │ ├── CompilerIdC │ │ │ │ ├── CMakeCCompilerId.c │ │ │ │ └── a.out │ │ │ └── CompilerIdCXX │ │ │ │ ├── CMakeCXXCompilerId.cpp │ │ │ │ └── a.out │ │ ├── CMakeDirectoryInformation.cmake │ │ ├── CMakeOutput.log │ │ ├── Makefile.cmake │ │ ├── Makefile2 │ │ ├── TargetDirectories.txt │ │ ├── cmake.check_cache │ │ ├── progress.marks │ │ ├── test_curd.dir │ │ │ ├── DBPool.cpp.o │ │ │ ├── DBPool.cpp.o.d │ │ │ ├── DependInfo.cmake │ │ │ ├── IMUser.cpp.o │ │ │ ├── IMUser.cpp.o.d │ │ │ ├── build.make │ │ │ ├── cmake_clean.cmake │ │ │ ├── compiler_depend.internal │ │ │ ├── compiler_depend.make │ │ │ ├── compiler_depend.ts │ │ │ ├── depend.make │ │ │ ├── flags.make │ │ │ ├── link.txt │ │ │ ├── progress.make │ │ │ ├── test_curd.cpp.o │ │ │ └── test_curd.cpp.o.d │ │ └── test_dbpool.dir │ │ │ ├── DBPool.cpp.o │ │ │ ├── DBPool.cpp.o.d │ │ │ ├── DependInfo.cmake │ │ │ ├── IMUser.cpp.o │ │ │ ├── IMUser.cpp.o.d │ │ │ ├── ZeroThreadpool.cpp.o │ │ │ ├── ZeroThreadpool.cpp.o.d │ │ │ ├── build.make │ │ │ ├── cmake_clean.cmake │ │ │ ├── compiler_depend.internal │ │ │ ├── compiler_depend.make │ │ │ ├── compiler_depend.ts │ │ │ ├── depend.make │ │ │ ├── flags.make │ │ │ ├── link.txt │ │ │ ├── progress.make │ │ │ ├── test_dbpool.cpp.o │ │ │ └── test_dbpool.cpp.o.d │ ├── Makefile │ ├── cmake_install.cmake │ ├── test_curd │ └── test_dbpool ├── test_curd.cpp ├── test_dbpool.cpp └── win32.h ├── 3.2.1原子操作与锁 └── lock.c ├── 3.2.2try-catch └── try-catch.c ├── 3.2.3定时器红黑树最小堆跳表时间轮 ├── mh-timer.c ├── mh-timer.h ├── minheap.c ├── minheap.h ├── rbt-timer.c ├── rbt-timer.h ├── rbtree.c ├── rbtree.h ├── readme.md ├── single_tw.c ├── skiplist.c ├── skiplist.h ├── skl-timer.c ├── spinlock.h ├── timewheel.c ├── timewheel.h └── tw-timer.c ├── 3.2.4无锁队列freequeue ├── 1_test_i++.c ├── 2_test_i++_threads.c ├── 3_test_mutex_spin_lock.cpp ├── 4_test_lock_free_queue.cpp ├── ArrayLockFreeQueue.h ├── ArrayLockFreeQueueImp.h ├── CMakeLists.txt ├── SimpleLockFreeQueue.h ├── atom_opt.h ├── atomic_ptr.hpp ├── readme.md ├── ypipe.hpp └── yqueue.hpp ├── 3.2.5死锁检测组件 ├── deadlock_success.c └── readme.md ├── 3.2.6内存泄漏检测组件 ├── first.c ├── mtrace.c ├── readme.md ├── second.c └── three.c ├── 3.3.1libevent-demo ├── libev │ ├── main-ev.c │ └── main-event.c └── libevent │ ├── evmain1.c │ └── evmain2.c ├── 3.3.2protobuf └── 2-protobuf │ ├── 1-im │ ├── .vscode │ │ └── settings.json │ ├── CMakeLists.txt │ ├── IM.BaseDefine.pb.cc │ ├── IM.BaseDefine.pb.h │ ├── IM.BaseDefine.proto │ ├── IM.Login.pb.cc │ ├── IM.Login.pb.h │ ├── IM.Login.proto │ ├── IM.Message.pb.cc │ ├── IM.Message.pb.h │ ├── IM.Message.proto │ ├── ImPduBase.cc │ ├── ImPduBase.h │ ├── Lock.cc │ ├── Lock.h │ ├── UtilPdu.cc │ ├── UtilPdu.h │ ├── bad │ ├── bad.cpp │ ├── client.cc │ ├── client_im │ ├── create.sh │ ├── helloworld.pb.cc │ ├── helloworld.pb.h │ ├── helloworld.proto │ ├── msg.pb.cc │ ├── msg.pb.h │ ├── msg.proto │ ├── ostype.h │ ├── pack_test │ ├── pack_test.cpp │ ├── rpc_client.cpp │ ├── rpc_server.cpp │ ├── server.cc │ ├── server_im │ ├── util.cc │ └── util.h │ ├── 2-im_new │ ├── CMakeLists.txt │ ├── IM.BaseDefine.pb.cc │ ├── IM.BaseDefine.pb.h │ ├── IM.BaseDefine.proto │ ├── IM.Login.pb.cc │ ├── IM.Login.pb.h │ ├── IM.Login.proto │ ├── IM.Message.pb.cc │ ├── IM.Message.pb.h │ ├── IM.Message.proto │ ├── ImPduBase.cc │ ├── ImPduBase.h │ ├── Lock.cc │ ├── Lock.h │ ├── Makefile │ ├── UtilPdu.cc │ ├── UtilPdu.h │ ├── client.cc │ ├── client_im │ ├── create.sh │ ├── msg.pb.cc │ ├── msg.pb.h │ ├── msg.proto │ ├── ostype.h │ ├── server.cc │ ├── server_im │ ├── util.cc │ └── util.h │ ├── 3-person │ ├── .vscode │ │ └── settings.json │ ├── CMakeLists.txt │ ├── IM.BaseDefine.pb.cc │ ├── IM.BaseDefine.pb.h │ ├── IM.Login.pb.cc │ ├── IM.Login.pb.h │ ├── code_test │ ├── code_test.cpp │ ├── pb_speed.cpp │ └── proto │ │ ├── IM.BaseDefine.proto │ │ ├── IM.Login.proto │ │ └── create.sh │ ├── 4-addressbook │ ├── add_person │ ├── add_person.cc │ ├── addressbook.pb.cc │ ├── addressbook.pb.h │ ├── addressbook.proto │ ├── book │ ├── core │ ├── list_people │ └── list_people.cc │ └── 5-codec │ ├── .vscode │ └── settings.json │ ├── CMakeLists.txt │ ├── Codec.pb.cc │ ├── Codec.pb.h │ ├── Codec.proto │ ├── code_test │ ├── code_test.cpp │ ├── proto │ ├── IM.BaseDefine.proto │ └── create.sh │ └── protobuf │ ├── any.h │ ├── any.pb.h │ ├── any.proto │ ├── api.pb.h │ ├── api.proto │ ├── arena.h │ ├── arena_impl.h │ ├── arenastring.h │ ├── compiler │ ├── code_generator.h │ ├── command_line_interface.h │ ├── cpp │ │ └── cpp_generator.h │ ├── csharp │ │ ├── csharp_generator.h │ │ └── csharp_names.h │ ├── importer.h │ ├── java │ │ ├── java_generator.h │ │ └── java_names.h │ ├── js │ │ ├── js_generator.h │ │ └── well_known_types_embed.h │ ├── objectivec │ │ ├── objectivec_generator.h │ │ └── objectivec_helpers.h │ ├── parser.h │ ├── php │ │ └── php_generator.h │ ├── plugin.h │ ├── plugin.pb.h │ ├── plugin.proto │ ├── python │ │ └── python_generator.h │ └── ruby │ │ └── ruby_generator.h │ ├── descriptor.h │ ├── descriptor.pb.h │ ├── descriptor.proto │ ├── descriptor_database.h │ ├── duration.pb.h │ ├── duration.proto │ ├── dynamic_message.h │ ├── empty.pb.h │ ├── empty.proto │ ├── extension_set.h │ ├── extension_set_inl.h │ ├── field_mask.pb.h │ ├── field_mask.proto │ ├── generated_enum_reflection.h │ ├── generated_enum_util.h │ ├── generated_message_reflection.h │ ├── generated_message_table_driven.h │ ├── generated_message_util.h │ ├── has_bits.h │ ├── implicit_weak_message.h │ ├── inlined_string_field.h │ ├── io │ ├── coded_stream.h │ ├── gzip_stream.h │ ├── printer.h │ ├── strtod.h │ ├── tokenizer.h │ ├── zero_copy_stream.h │ ├── zero_copy_stream_impl.h │ └── zero_copy_stream_impl_lite.h │ ├── map.h │ ├── map_entry.h │ ├── map_entry_lite.h │ ├── map_field.h │ ├── map_field_inl.h │ ├── map_field_lite.h │ ├── map_type_handler.h │ ├── message.h │ ├── message_lite.h │ ├── metadata.h │ ├── metadata_lite.h │ ├── parse_context.h │ ├── port.h │ ├── port_def.inc │ ├── port_undef.inc │ ├── reflection.h │ ├── reflection_ops.h │ ├── repeated_field.h │ ├── service.h │ ├── source_context.pb.h │ ├── source_context.proto │ ├── struct.pb.h │ ├── struct.proto │ ├── stubs │ ├── bytestream.h │ ├── callback.h │ ├── casts.h │ ├── common.h │ ├── fastmem.h │ ├── hash.h │ ├── logging.h │ ├── macros.h │ ├── mutex.h │ ├── once.h │ ├── platform_macros.h │ ├── port.h │ ├── status.h │ ├── stl_util.h │ ├── stringpiece.h │ ├── strutil.h │ └── template_util.h │ ├── text_format.h │ ├── timestamp.pb.h │ ├── timestamp.proto │ ├── type.pb.h │ ├── type.proto │ ├── unknown_field_set.h │ ├── util │ ├── delimited_message_util.h │ ├── field_comparator.h │ ├── field_mask_util.h │ ├── json_util.h │ ├── message_differencer.h │ ├── time_util.h │ ├── type_resolver.h │ └── type_resolver_util.h │ ├── wire_format.h │ ├── wire_format_lite.h │ ├── wrappers.pb.h │ └── wrappers.proto ├── readme.md └── 文件服务器项目 ├── day1fastdfs ├── fdfs_upload_file.c ├── fdfs_upload_file.h └── main.c ├── day2redis ├── myredis.c └── redis命令参考官方文档中文版.pdf ├── day3nginx ├── Nginx配置说明.doc ├── SwitchHosts │ ├── SwitchHosts.exe │ ├── configs.json │ └── hosts │ │ ├── 0.hosts │ │ ├── 0.hosts.backup_switchhosts │ │ ├── 1.hosts.backup_switchhosts │ │ ├── COMMON.hosts │ │ └── COMMON.hosts.backup_switchhosts ├── nginx-1.12.0 │ ├── conf │ │ ├── fastcgi.conf │ │ ├── fastcgi_params │ │ ├── koi-utf │ │ ├── koi-win │ │ ├── mime.types │ │ ├── nginx.conf │ │ ├── scgi_params │ │ ├── uwsgi_params │ │ └── win-utf │ ├── contrib │ │ ├── README │ │ ├── geo2nginx.pl │ │ ├── unicode2nginx │ │ │ ├── koi-utf │ │ │ ├── unicode-to-nginx.pl │ │ │ └── win-utf │ │ └── vim │ │ │ ├── ftdetect │ │ │ └── nginx.vim │ │ │ ├── ftplugin │ │ │ └── nginx.vim │ │ │ ├── indent │ │ │ └── nginx.vim │ │ │ └── syntax │ │ │ └── nginx.vim │ ├── docs │ │ ├── CHANGES │ │ ├── CHANGES.ru │ │ ├── LICENSE │ │ ├── OpenSSL.LICENSE │ │ ├── PCRE.LICENCE │ │ ├── README │ │ └── zlib.LICENSE │ ├── html │ │ ├── 50x.html │ │ └── index.html │ └── nginx.exe ├── nginx-1.16.1.tar.gz ├── openssl-1.1.1g.tar.gz ├── pcre-8.44.tar.gz ├── yundisk.tar.gz └── zlib-1.2.11.tar.gz ├── day4fastCGI ├── fcgi-2.4.1-SNAP-0910052249.tar.gz ├── spawn-fcgi-1.6.4.tar.gz └── zyFile2.tar.gz ├── day5nginx+fastDFS └── fastdfs-nginx-module-1.22.tar.gz └── day6数据库以及接口设计 ├── gopher.sql ├── nginx.conf └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | out 4 | gen 5 | .git 6 | .github 7 | cmake-build-debug -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/1-1-error-example.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() { 7 | cout << "Hello World!" << endl; 8 | { 9 | int *ptr = new int; 10 | shared_ptr p1(ptr); 11 | shared_ptr p2(ptr); // 逻辑错误 12 | } 13 | function(shared_ptr(new int), g()); //有缺陷 14 | 15 | cout << "finish" << endl; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/1-3-1-delete.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | void DeleteIntPtr(int *p) { 7 | cout << "call DeleteIntPtr" << endl; 8 | delete p; 9 | } 10 | 11 | int main() { 12 | 13 | int *ptr = new int; 14 | shared_ptr p1(ptr); 15 | shared_ptr p2(ptr); // 逻辑错误 16 | 17 | std::shared_ptr p(new int(1), DeleteIntPtr); 18 | std::shared_ptr p2(new int(1), [](int *p) { 19 | cout << "call lambda1 delete p" << endl; 20 | delete p; 21 | }); 22 | std::shared_ptr p3(new int[10], [](int *p) { 23 | cout << "call lambda2 delete p" << endl; 24 | delete[] p; // 数组删除 25 | }); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/1-3-1-reset-count.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | void test(shared_ptr sp) { 7 | // sp在test里面的作用域 8 | cout << "test sp.use_count()" << sp.use_count() << endl; 9 | } 10 | 11 | int main2() { 12 | auto sp1 = make_shared(100); // 优先使用make_shared来构造智能指针 13 | //相当于 14 | shared_ptr sp2(new int(100)); 15 | 16 | // std::shared_ptr p = new int(1); // 不能将一个原始指针直接赋值给一个智能指针 17 | // int *p = new int(1); 18 | std::shared_ptr p1; 19 | p1.reset(new int(1)); // 分配资源。 20 | if (p1) { 21 | cout << "p1 ptr new int(1) \n"; 22 | } 23 | // p1.reset(); 24 | // if(!p1) { 25 | // cout << "p1 ptr NULL \n"; 26 | // } 27 | std::shared_ptr p2 = p1; 28 | 29 | // // 引用计数此时应该是2 30 | cout << "p2.use_count() = " << p2.use_count() << endl; // 2 31 | p1.reset(); // 释放资源 32 | 33 | // cout << "p1.reset()\n"; 34 | // // 引用计数此时应该是1 35 | cout << "p2.use_count()= " << p2.use_count() << endl; // 1 36 | if (!p1) { // p1是空的 true false 37 | cout << "p1 is empty\n"; 38 | } 39 | if (!p2) { // p2非空 40 | cout << "p2 is empty\n"; 41 | } 42 | 43 | //裸指针 44 | int *p = nullptr; 45 | p2.reset(); 46 | cout << "p2.reset()\n"; 47 | cout << "p2.use_count()= " << p2.use_count() << endl; 48 | if (!p2) { 49 | cout << "p2 is empty\n"; 50 | } 51 | 52 | shared_ptr sp5(new int(100)); 53 | test(sp5); 54 | cout << "sp5.use_count()" << sp5.use_count() << endl; 55 | return 0; 56 | } 57 | 58 | int main() { 59 | { 60 | int *ptr = new int; 61 | shared_ptr p1(ptr); 62 | shared_ptr p2(ptr); // 逻辑错误 63 | cout << "p1.use_count()= " << p1.use_count() << endl; 64 | cout << "p2.use_count()= " << p2.use_count() << endl; 65 | } 66 | cout << "main end\n"; 67 | } 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/1-3-2-cycle-shared-ptr.cpp: -------------------------------------------------------------------------------- 1 | // 1-3-2-cycle-shared-ptr 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | class A; 9 | 10 | class B; 11 | 12 | class A { 13 | public: 14 | std::shared_ptr bptr; 15 | 16 | ~A() { 17 | cout << "A is deleted" << endl; 18 | } 19 | }; 20 | 21 | class B { 22 | public: 23 | std::shared_ptr aptr; 24 | 25 | ~B() { 26 | cout << "B is deleted" << endl; 27 | } 28 | }; 29 | 30 | int main() { 31 | { 32 | std::shared_ptr ap(new A); 33 | std::shared_ptr bp(new B); 34 | ap->bptr = bp; 35 | bp->aptr = ap; 36 | } 37 | cout << "main leave" << endl; // 循环引用导致ap bp退出了作用域都没有析构 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/1-3-2-shared_from_this.cpp: -------------------------------------------------------------------------------- 1 | //1-1-shared_from_this 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | class A { 8 | public: 9 | shared_ptr GetSelf() { 10 | return shared_ptr(this); // 不要这么做 11 | } 12 | 13 | A() { 14 | cout << "Construction A" << endl; 15 | } 16 | 17 | ~A() { 18 | cout << "Destruction A: " << this << endl; 19 | } 20 | }; 21 | 22 | int main() { 23 | shared_ptr sp1(new A); 24 | shared_ptr sp2 = sp1->GetSelf(); 25 | cout << "sp1.use_count() = " << sp1.use_count() << endl; 26 | cout << "sp2.use_count() = " << sp2.use_count() << endl; 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/1-3-2-shared_from_this2.cpp: -------------------------------------------------------------------------------- 1 | //1-1-shared_from_this2 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | class A : public std::enable_shared_from_this { 8 | public: 9 | shared_ptr GetSelf() { 10 | return shared_from_this(); // 11 | } 12 | 13 | A() { 14 | cout << "Construction A" << endl; 15 | } 16 | 17 | ~A() { 18 | cout << "Destruction A" << endl; 19 | } 20 | }; 21 | 22 | int main() { 23 | shared_ptr sp1(new A); 24 | shared_ptr sp2 = sp1->GetSelf(); // ok 25 | cout << "sp1.use_count() = " << sp1.use_count() << endl; 26 | cout << "sp2.use_count() = " << sp2.use_count() << endl; 27 | cout << "leave {}" << endl; 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/1-4-unique_ptr-deleter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | struct MyDelete { 7 | void operator()(int *p) { 8 | cout << "delete" << endl; 9 | delete p; 10 | } 11 | }; 12 | 13 | int main() { 14 | auto upw1(std::make_unique(2)); // with make func 15 | std::unique_ptr upw2(new int); // without make func 16 | auto upw3 = std::make_unique(2); // with make func 17 | 18 | upw1[21] = 1; 19 | std::unique_ptr ptr2(new int(1)); 20 | // auto ptr(std::make_unique(1)); 21 | cout << "main finish! " << upw1[1] << endl; 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/1-4-unique_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | void test1() { 7 | unique_ptr my_ptr(new int); // 正确 8 | if (!my_ptr) { 9 | cout << "1 my_ptr is null" << endl; 10 | } 11 | 12 | unique_ptr my_other_ptr = std::move(my_ptr); // 正确 13 | if (!my_ptr) { 14 | cout << "2 my_ptr is null" << endl; 15 | } 16 | if (!my_other_ptr) { 17 | cout << "2 my_other_ptr is null" << endl; 18 | } 19 | } 20 | 21 | void test2() { 22 | // unique_ptr可以指向一个数组 23 | std::unique_ptr ptr(new int[10]); 24 | ptr[9] = 9; 25 | 26 | // std::shared_ptr ptr2(new int[10]); // 这个是不合法的 27 | 28 | // unique_ptr指定删除器和shared_ptr有区别 29 | std::shared_ptr ptr3(new int(1), [](int *p) { delete p; }); // 正确 30 | // std::unique_ptr ptr4(new int(1), [](int *p){delete p;}); // 错误 31 | 32 | std::unique_ptr ptr5(new int(1), [](int *p) { delete p; }); // 正确 33 | 34 | std::unique_ptr ptr6(new int(1), [](int *p) { delete p; }); // 正确 35 | cout << "main finish!" << endl; 36 | } 37 | 38 | int main() { 39 | test1(); 40 | // test2(); 41 | cout << "main finish!" << endl; 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/1-5-1-weak_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | std::weak_ptr gw; 8 | 9 | void f() { 10 | auto spt = gw.lock(); // 11 | if (gw.expired()) { 12 | cout << "gw Invalid, resource released"; 13 | } 14 | else { 15 | cout << "gw Valid, *spt = " << *spt << endl; 16 | } 17 | } 18 | 19 | 20 | int main1() { 21 | { 22 | auto sp = std::make_shared(42); 23 | gw = sp; 24 | f(); 25 | } 26 | f(); 27 | return 0; 28 | } 29 | 30 | void f2() { 31 | cout << "lock\n"; 32 | auto spt = gw.lock(); // 锁好资源再去判断是否有效 33 | std::this_thread::sleep_for(std::chrono::seconds(2)); 34 | if (gw.expired()) { 35 | cout << "gw Invalid, resource released\n"; 36 | } 37 | else { 38 | cout << "gw Valid, *spt = " << *spt << endl; 39 | } 40 | } 41 | 42 | int main() { 43 | 44 | 45 | 46 | { 47 | auto sp = std::make_shared(42); 48 | gw = sp; 49 | std::thread([&]() { 50 | std::this_thread::sleep_for(std::chrono::seconds(1)); 51 | 52 | cout << "sp reset\n"; 53 | sp.reset(); 54 | }).detach(); 55 | 56 | f2(); 57 | } 58 | f2(); 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/1-5-4-misuse-weak_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | std::weak_ptr gw; 6 | 7 | 8 | 9 | 10 | void test1() { 11 | cout << "---- test1 ------------------" << endl; 12 | weak_ptr wp; 13 | { 14 | shared_ptr sp(new int(1)); //sp.use_count()==1 15 | wp = sp; //wp不会改变引用计数,所以sp.use_count()==1 16 | shared_ptr sp_ok = wp.lock(); //wp没有重载->操作符。只能这样取所指向的对象 17 | } 18 | shared_ptr sp_null = wp.lock(); //sp_null .use_count()==0; 19 | if (wp.expired()) { 20 | cout << "shared_ptr is destroy" << endl; 21 | } 22 | else { 23 | cout << "shared_ptr no destroy" << endl; 24 | } 25 | } 26 | 27 | void test2() { 28 | cout << "---- test2 ------------------" << endl; 29 | weak_ptr wp; 30 | shared_ptr sp_ok; 31 | { 32 | shared_ptr sp(new int(1)); //sp.use_count()==1 33 | wp = sp; //wp不会改变引用计数,所以sp.use_count()==1 34 | sp_ok = wp.lock(); //wp没有重载->操作符。只能这样取所指向的对象 35 | } 36 | 37 | if (wp.expired()) { 38 | cout << "shared_ptr is destroy" << endl; 39 | } 40 | else { 41 | cout << "shared_ptr no destroy" << endl; 42 | } 43 | } 44 | 45 | int main() { 46 | test1(); 47 | test2(); 48 | return 0; 49 | } 50 | void fn(shared_ptrsp) { 51 | ... 52 | if(..){ 53 | sp = other_sp; 54 | } else { 55 | sp = other_sp2; 56 | } 57 | } -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/2-1-lr_value.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | /* 6 | 1. 什么是左值、右值 7 | - 左值可以取地址、位于等号左边; 8 | - 而右值没法取地址,位于等号右边。 9 | */ 10 | 11 | void test1() { 12 | struct A { 13 | A(int a = 0) { 14 | a_ = a; 15 | } 16 | 17 | int a_; 18 | }; 19 | 20 | A a = A(); 21 | } 22 | 23 | int main() { 24 | cout << "Hello World!" << endl; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/2-1-mystring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | //2-1-mystring 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | class MyString { 11 | private: 12 | char *m_data; 13 | size_t m_len; 14 | 15 | void copy_data(const char *s) { 16 | m_data = new char[m_len + 1]; 17 | memcpy(m_data, s, m_len); 18 | m_data[m_len] = '\0'; 19 | } 20 | 21 | public: 22 | MyString() { 23 | m_data = NULL; 24 | m_len = 0; 25 | } 26 | 27 | MyString(const char *p) { 28 | m_len = strlen(p); 29 | copy_data(p); 30 | } 31 | 32 | MyString(const MyString &str) { 33 | m_len = str.m_len; 34 | copy_data(str.m_data); 35 | std::cout << "Copy Constructor is called! source: " << str.m_data << std::endl; 36 | } 37 | 38 | MyString &operator=(const MyString &str) { 39 | if (this != &str) { 40 | m_len = str.m_len; 41 | copy_data(str.m_data); 42 | } 43 | std::cout << "Copy Assignment is called! source: " << str.m_data << std::endl; 44 | return *this; 45 | } 46 | 47 | // 用c++11的右值引用来定义这两个函数 48 | MyString(MyString &&str) { 49 | std::cout << "Move Constructor is called! source: " << str.m_data << std::endl; 50 | m_len = str.m_len; 51 | m_data = str.m_data; //避免了不必要的拷贝 52 | str.m_len = 0; 53 | str.m_data = NULL; 54 | } 55 | 56 | MyString &operator=(MyString &&str) { 57 | std::cout << "Move Assignment is called! source: " << str.m_data << std::endl; 58 | if (this != &str) { 59 | m_len = str.m_len; 60 | m_data = str.m_data; //避免了不必要的拷贝 61 | str.m_len = 0; 62 | str.m_data = NULL; 63 | } 64 | return *this; 65 | } 66 | 67 | virtual ~MyString() { 68 | if (m_data) free(m_data); 69 | } 70 | }; 71 | 72 | void test() { 73 | MyString a; 74 | a = MyString("Hello"); 75 | std::vector vec; 76 | vec.push_back(MyString("World")); 77 | } 78 | 79 | int main() { 80 | test(); 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/2-2-3-1-r-move.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | void test1() { 6 | cout << "test2!" << endl; 7 | int a = 5; // a是个左值 8 | int &ref_a_left = a; // 左值引用指向左值 9 | int &&ref_a_right = std::move(a); // 通过std::move将左值转化为右值,可以被右值引用指向 10 | 11 | cout << "a:" << a << endl; // 打印结果:5 12 | } 13 | 14 | void test2() { 15 | cout << "test2!" << endl; 16 | int &&ref_a = 5; 17 | ref_a = 6; 18 | } 19 | 20 | void test3() { 21 | cout << "test3!" << endl; 22 | int temp = 5; 23 | int &&ref_a = std::move(temp); // 24 | ref_a = 6; 25 | cout << "temp:" << temp << ", ref_a:" << ref_a << endl; 26 | } 27 | 28 | int main() { 29 | 30 | test1(); 31 | test2(); 32 | test3(); 33 | return 0; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/2-2-3-2-r-move.cpp: -------------------------------------------------------------------------------- 1 | // 2-2-3-2-r-move 2 | //被声明出来的左、右值引用都是左值**。 因为被声明出的左右值引用是**有地址的**,也位于等号左边。 3 | #include 4 | 5 | using namespace std; 6 | 7 | // 形参是个右值引用 8 | void change(int &&right_value) { 9 | right_value = 8; 10 | } 11 | 12 | int main() { 13 | int a = 5; // a是个左值 14 | int &ref_a_left = a; // ref_a_left是个左值引用 15 | int &&ref_a_right = std::move(a); // ref_a_right是个右值引用 16 | 17 | // change(a); // 编译不过,a是左值,change参数要求右值 18 | // change(ref_a_left); // 编译不过,左值引用ref_a_left本身也是个左值 19 | // change(ref_a_right); // 编译不过,右值引用ref_a_right本身也是个左值 20 | 21 | change(std::move(a)); // 编译通过 22 | change(std::move(ref_a_right)); // 编译通过 23 | change(std::move(ref_a_left)); // 编译通过 24 | 25 | change(5); // 当然可以直接接右值,编译通过 26 | 27 | cout << &a << ' '; 28 | cout << &ref_a_left << ' '; 29 | cout << &ref_a_right; 30 | // 打印这三个左值的地址,都是一样的 31 | } 32 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/2-3-1-memory.cpp: -------------------------------------------------------------------------------- 1 | //2-1-memory 2 | #include 3 | 4 | using namespace std; 5 | 6 | class A { 7 | public: 8 | A() : m_ptr(new int(0)) { 9 | cout << "constructor A" << endl; 10 | } 11 | 12 | // A(const A& a) :m_ptr(new int(*a.m_ptr)) { // 拷贝构造函数 13 | // cout << "copy constructor A" << endl; 14 | // } 15 | ~A() { 16 | cout << "destructor A, m_ptr:" << m_ptr << endl; 17 | delete m_ptr; 18 | m_ptr = nullptr; 19 | } 20 | 21 | private: 22 | int *m_ptr; 23 | }; 24 | 25 | // 为了避免返回值被优化,此函数故意这样写 26 | A Get(bool flag) { 27 | A a1; 28 | A a2; 29 | cout << "ready return" << endl; 30 | if (flag) 31 | return a1; 32 | else 33 | return a2; 34 | } 35 | 36 | int main() { 37 | 38 | { 39 | printf("Get before\n"); 40 | A a = Get(false); // 运行报错 41 | printf("Get after\n"); 42 | } 43 | cout << "main finish" << endl; 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/2-3-1-memory2.cpp: -------------------------------------------------------------------------------- 1 | //2-1-memory2 2 | #include 3 | 4 | using namespace std; 5 | 6 | class A { 7 | public: 8 | A() : m_ptr(new int(0)) { 9 | cout << "constructor A" << endl; 10 | } 11 | 12 | A(const A &a) : m_ptr(new int(*a.m_ptr)) { 13 | cout << "copy constructor A" << endl; 14 | } 15 | 16 | ~A() { 17 | cout << "destructor A, m_ptr:" << m_ptr << endl; 18 | delete m_ptr; 19 | m_ptr = nullptr; 20 | } 21 | 22 | private: 23 | int *m_ptr; 24 | }; 25 | 26 | // 为了避免返回值优化,此函数故意这样写 27 | A Get(bool flag) { 28 | A a; 29 | A b; 30 | cout << "ready return" << endl; 31 | if (flag) 32 | return a; 33 | else 34 | return b; 35 | } 36 | 37 | int main() { 38 | { 39 | A a = Get(false); // 正确运行 40 | } 41 | cout << "main finish" << endl; 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/2-3-1-memory3.cpp: -------------------------------------------------------------------------------- 1 | //2-1-memory3 2 | #include 3 | 4 | using namespace std; 5 | 6 | class A { 7 | public: 8 | A() : m_ptr(new int(0)) { 9 | cout << "constructor A" << endl; 10 | } 11 | 12 | A(const A &a) : m_ptr(new int(*a.m_ptr)) { 13 | cout << "copy constructor A" << endl; 14 | } 15 | 16 | // 优先右值引用 17 | // A(A&& a) :m_ptr(a.m_ptr) { 18 | // a.m_ptr = nullptr; 19 | // cout << "move constructor A" << endl; 20 | // } 21 | 22 | ~A() { 23 | cout << "destructor A, m_ptr:" << m_ptr << endl; 24 | if (m_ptr) 25 | delete m_ptr; 26 | } 27 | 28 | private: 29 | int *m_ptr; 30 | }; 31 | 32 | // 为了避免返回值优化,此函数故意这样写 33 | A Get(bool flag) { 34 | A a; 35 | A b; 36 | cout << "ready return" << endl; 37 | if (flag) 38 | return a; 39 | else 40 | return b; 41 | } 42 | 43 | int main() { 44 | { 45 | A a = Get(false); // 正确运行 46 | } 47 | cout << "main finish" << endl; 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/2-3-2-move.cpp: -------------------------------------------------------------------------------- 1 | //2-3-2-move 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | class MyString { 11 | private: 12 | char *m_data; 13 | size_t m_len; 14 | 15 | void copy_data(const char *s) { 16 | m_data = new char[m_len + 1]; 17 | memcpy(m_data, s, m_len); 18 | m_data[m_len] = '\0'; 19 | } 20 | 21 | public: 22 | MyString() { 23 | m_data = NULL; 24 | m_len = 0; 25 | } 26 | 27 | MyString(const char *p) { 28 | m_len = strlen(p); 29 | copy_data(p); 30 | } 31 | 32 | MyString(const MyString &str) { 33 | m_len = str.m_len; 34 | copy_data(str.m_data); 35 | std::cout << "Copy Constructor is called! source: " << str.m_data << std::endl; 36 | } 37 | 38 | MyString &operator=(const MyString &str) { 39 | if (this != &str) { 40 | m_len = str.m_len; 41 | copy_data(str.m_data); 42 | } 43 | std::cout << "Copy Assignment is called! source: " << str.m_data << std::endl; 44 | return *this; 45 | } 46 | 47 | // 用c++11的右值引用来定义这两个函数 48 | MyString(MyString &&str) { 49 | std::cout << "Move Constructor is called! source: " << str.m_data << std::endl; 50 | m_len = str.m_len; 51 | m_data = str.m_data; //避免了不必要的拷贝 52 | str.m_len = 0; 53 | str.m_data = NULL; 54 | } 55 | 56 | MyString &operator=(MyString &&str) { 57 | std::cout << "Move Assignment is called! source: " << str.m_data << std::endl; 58 | if (this != &str) { 59 | m_len = str.m_len; 60 | m_data = str.m_data; //避免了不必要的拷贝 61 | str.m_len = 0; 62 | str.m_data = NULL; 63 | } 64 | return *this; 65 | } 66 | 67 | virtual ~MyString() { 68 | if (m_data) free(m_data); 69 | } 70 | }; 71 | 72 | 73 | int main() { 74 | MyString a; 75 | a = MyString("Hello"); // Move Assignment 76 | MyString b = a; // Copy Constructor 77 | MyString c = std::move(a); // Move Constructor is called! 将左值转为右值 78 | 79 | std::vector vec; 80 | vec.push_back(MyString("World")); // Move Constructor is called! 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/2-3-3-forward1.cpp: -------------------------------------------------------------------------------- 1 | // 2-3-2-forward1 2 | #include 3 | 4 | using namespace std; 5 | 6 | template 7 | void Print(T &t) { 8 | cout << "L" << t << endl; 9 | } 10 | 11 | template 12 | void Print(T &&t) { 13 | cout << "R" << t << endl; 14 | } 15 | 16 | template 17 | void func(T &&t) { 18 | Print(t); 19 | Print(std::move(t)); 20 | Print(std::forward(t)); 21 | } 22 | 23 | int main() { 24 | cout << "-- func(1)" << endl; 25 | func(1); 26 | int x = 10; 27 | int y = 20; 28 | cout << "\n-- func(x)" << endl; 29 | func(x); // x本身是左值 30 | cout << "\n-- func(std::forward(y))" << endl; 31 | func(std::forward(y)); ////T为int,以右值方式转发y 32 | cout << "\n-- func(std::forward(y))" << endl; 33 | func(std::forward(y)); 34 | cout << "\n-- func(std::forward(y))" << endl; 35 | func(std::forward(y)); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/2-3-3-forward2.cpp: -------------------------------------------------------------------------------- 1 | //2-3-3-forward2 2 | #include "stdio.h" 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | class A { 10 | public: 11 | A() : m_ptr(NULL), m_nSize(0) {} 12 | 13 | A(int *ptr, int nSize) { 14 | m_nSize = nSize; 15 | m_ptr = new int[nSize]; 16 | printf("A(int *ptr, int nSize) m_ptr:%p\n", m_ptr); 17 | if (m_ptr) { 18 | memcpy(m_ptr, ptr, sizeof(sizeof(int) * nSize)); 19 | } 20 | } 21 | 22 | A(const A &other) // 拷贝构造函数实现深拷贝 23 | { 24 | m_nSize = other.m_nSize; 25 | if (other.m_ptr) { 26 | printf("A(const A &other) m_ptr:%p\n", m_ptr); 27 | if (m_ptr) 28 | delete[] m_ptr; 29 | printf("delete[] m_ptr\n"); 30 | m_ptr = new int[m_nSize]; 31 | memcpy(m_ptr, other.m_ptr, sizeof(sizeof(int) * m_nSize)); 32 | } 33 | else { 34 | if (m_ptr) 35 | delete[] m_ptr; 36 | m_ptr = NULL; 37 | } 38 | cout << "A(const int &i)" << endl; 39 | } 40 | 41 | // 右值引用移动构造函数 42 | A(A &&other) { 43 | m_ptr = NULL; 44 | m_nSize = other.m_nSize; 45 | if (other.m_ptr) { 46 | m_ptr = move(other.m_ptr); // 移动语义 47 | other.m_ptr = NULL; 48 | } 49 | } 50 | 51 | ~A() { 52 | if (m_ptr) { 53 | delete[] m_ptr; 54 | m_ptr = NULL; 55 | } 56 | } 57 | 58 | void deleteptr() { 59 | if (m_ptr) { 60 | delete[] m_ptr; 61 | m_ptr = NULL; 62 | } 63 | } 64 | 65 | int *m_ptr = NULL; // 增加初始化 66 | int m_nSize = 0; 67 | }; 68 | 69 | int main() { 70 | int arr[] = {1, 2, 3}; 71 | A a(arr, sizeof(arr) / sizeof(arr[0])); 72 | cout << "m_ptr in a Addr: 0x" << a.m_ptr << endl; 73 | A b(a); 74 | cout << "m_ptr in b Addr: 0x" << b.m_ptr << endl; 75 | 76 | b.deleteptr(); 77 | A c(std::forward(a)); // 完美转换 78 | cout << "m_ptr in c Addr: 0x" << c.m_ptr << endl; 79 | c.deleteptr(); 80 | vector vect{1, 2, 3, 4, 5}; 81 | cout << "before move vect size: " << vect.size() << endl; 82 | vector vect1 = move(vect); 83 | cout << "after move vect size: " << vect.size() << endl; 84 | cout << "new vect1 size: " << vect1.size() << endl; 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/2-3-4-emplace_back.cpp: -------------------------------------------------------------------------------- 1 | //2-5-emplace_back 2 | #include 3 | #include 4 | #include "time_interval.h" 5 | 6 | int main() { 7 | 8 | 9 | std::vector v; 10 | int count = 10000000; 11 | v.reserve(count); //预分配十万大小,排除掉分配内存的时间 12 | { 13 | TIME_INTERVAL_SCOPE("push_back string:"); 14 | for (int i = 0; i < count; i++) { 15 | std::string temp("ceshi"); 16 | v.push_back(temp);// push_back(const string&),参数是左值引用 17 | } 18 | } 19 | 20 | v.clear(); 21 | { 22 | TIME_INTERVAL_SCOPE("push_back move(string):"); 23 | for (int i = 0; i < count; i++) { 24 | std::string temp("ceshi"); 25 | v.push_back(std::move(temp));// push_back(string &&), 参数是右值引用 26 | } 27 | } 28 | 29 | v.clear(); 30 | { 31 | TIME_INTERVAL_SCOPE("push_back(string):"); 32 | for (int i = 0; i < count; i++) { 33 | v.push_back(std::string("ceshi"));// push_back(string &&), 参数是右值引用 34 | } 35 | } 36 | 37 | v.clear(); 38 | { 39 | TIME_INTERVAL_SCOPE("push_back(c string):"); 40 | for (int i = 0; i < count; i++) { 41 | v.push_back("ceshi");// push_back(string &&), 参数是右值引用 42 | } 43 | } 44 | 45 | v.clear(); 46 | { 47 | TIME_INTERVAL_SCOPE("emplace_back(c string):"); 48 | for (int i = 0; i < count; i++) { 49 | v.emplace_back("ceshi");// 只有一次构造函数,不调用拷贝构造函数,速度最快 50 | } 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/2-3-4-emplace_back2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "time_interval.h" 4 | 5 | using namespace std; 6 | 7 | class Foo { 8 | public: 9 | Foo(std::string str) : name(str) { 10 | std::cout << "constructor" << std::endl; 11 | } 12 | 13 | Foo(const Foo &f) : name(f.name) { 14 | std::cout << "copy constructor" << std::endl; 15 | } 16 | 17 | Foo(Foo &&f) : name(std::move(f.name)) { 18 | std::cout << "move constructor" << std::endl; 19 | } 20 | 21 | private: 22 | std::string name; 23 | }; 24 | 25 | int main() { 26 | 27 | 28 | std::vector v; 29 | int count = 10000000; 30 | v.reserve(count); //预分配十万大小,排除掉分配内存的时间 31 | 32 | { 33 | TIME_INTERVAL_SCOPE("push_back T:"); 34 | Foo temp("test"); 35 | v.push_back(temp);// push_back(const T&),参数是左值引用 36 | //打印结果: 37 | //constructor 38 | //copy constructor 39 | } 40 | cout << " ---------------------\n" << endl; 41 | v.clear(); 42 | { 43 | TIME_INTERVAL_SCOPE("push_back move(T):"); 44 | Foo temp("test"); 45 | v.push_back(std::move(temp));// push_back(T &&), 参数是右值引用 46 | //打印结果: 47 | //constructor 48 | //move constructor 49 | } 50 | cout << " ---------------------\n" << endl; 51 | v.clear(); 52 | { 53 | TIME_INTERVAL_SCOPE("push_back(T&&):"); 54 | v.push_back(Foo("test"));// push_back(T &&), 参数是右值引用 55 | //打印结果: 56 | //constructor 57 | //move constructor 58 | } 59 | cout << " ---------------------\n" << endl; 60 | v.clear(); 61 | { 62 | std::string temp = "test"; 63 | TIME_INTERVAL_SCOPE("push_back(string):"); 64 | v.push_back(temp);// push_back(T &&), 参数是右值引用 65 | //打印结果: 66 | //constructor 67 | //move constructor 68 | } 69 | cout << " ---------------------\n" << endl; 70 | v.clear(); 71 | { 72 | std::string temp = "test"; 73 | TIME_INTERVAL_SCOPE("emplace_back(string):"); 74 | v.emplace_back(temp);// 只有一次构造函数,不调用拷贝构造函数,速度最快 75 | //打印结果: 76 | //constructor 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/4-priority_queue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | template 7 | void print_queue(T &q) { 8 | while (!q.empty()) { 9 | std::cout << q.top() << " "; 10 | q.pop(); 11 | } 12 | std::cout << '\n'; 13 | } 14 | 15 | int main() { 16 | std::priority_queue q; 17 | 18 | for (int n: {1, 8, 5, 6, 3, 4, 0, 9, 7, 2}) 19 | q.push(n); 20 | 21 | print_queue(q); 22 | 23 | std::priority_queue, std::greater > q2; 24 | 25 | for (int n: {1, 8, 5, 6, 3, 4, 0, 9, 7, 2}) 26 | q2.push(n); 27 | 28 | print_queue(q2); 29 | 30 | // 用 lambda 比较元素。如果是自定的对象插入priority_queue,要自己写比较函数 31 | // auto cmp = [](int left, int right) { return (left) < (right); }; // 从大到小排序 32 | auto cmp = [](int left, int right) { return (left) > (right); }; // 从小到大排序 33 | std::priority_queue, decltype(cmp)> q3(cmp); 34 | 35 | for (int n: {1, 8, 5, 6, 3, 4, 0, 9, 7, 2}) 36 | q3.push(n); 37 | 38 | print_queue(q3); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/4-unordered_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void unordered_map_test() { 7 | std::cout << "unordered_map_test\n"; 8 | // 创建三个 string 的 unordered_map (映射到 string ) 9 | std::unordered_map u = { 10 | {"2RED", "#FF0000"}, 11 | {"1GREEN", "#00FF00"}, 12 | {"3BLUE", "#0000FF"}, 13 | {"a", "#0000FF"}, 14 | {"b", "#0000FF"} 15 | }; 16 | 17 | // 迭代并打印 unordered_map 的关键和值 18 | for (const auto &n: u) { 19 | std::cout << "Key:[" << n.first << "] Value:[" << n.second << "]\n"; 20 | } 21 | 22 | // 添加新入口到 unordered_map 23 | u["BLACK"] = "#000000"; 24 | u["WHITE"] = "#FFFFFF"; 25 | 26 | // 用关键输出值 27 | std::cout << "The HEX of color RED is:[" << u["RED"] << "]\n"; 28 | std::cout << "The HEX of color BLACK is:[" << u["BLACK"] << "]\n"; 29 | } 30 | 31 | void ordered_map_test() { 32 | std::cout << "\nordered_map_test\n"; 33 | // 创建三个 string 的 unordered_map (映射到 string ) 34 | std::map u = { 35 | {"2RED", "#FF0000"}, 36 | {"1GREEN", "#00FF00"}, 37 | {"3BLUE", "#0000FF"}, 38 | {"a", "#0000FF"}, 39 | {"b", "#0000FF"} 40 | }; 41 | 42 | // 迭代并打印 unordered_map 的关键和值 43 | for (const auto &n: u) { 44 | std::cout << "Key:[" << n.first << "] Value:[" << n.second << "]\n"; 45 | } 46 | 47 | // 添加新入口到 unordered_map 48 | u["BLACK"] = "#000000"; 49 | u["WHITE"] = "#FFFFFF"; 50 | 51 | // 用关键输出值 52 | std::cout << "The HEX of color RED is:[" << u["RED"] << "]\n"; 53 | std::cout << "The HEX of color BLACK is:[" << u["BLACK"] << "]\n"; 54 | } 55 | 56 | int main() { 57 | unordered_map_test(); 58 | ordered_map_test(); 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | project(C++11) 4 | # 设置C++标准为 C++ 11 5 | # set(CMAKE_CXX_STANDARD 11) 6 | # 设置C++标准为 C++ 14 7 | set(CMAKE_CXX_STANDARD 14) 8 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 9 | set(CMAKE_BUILD_TYPE "Debug") 10 | set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g") 11 | add_executable(1-1-error-example 1-1-error-example.cpp) 12 | add_executable(1-2-shared_ptr-app 1-2-shared_ptr-app.cpp) 13 | target_link_libraries(1-2-shared_ptr-app pthread) 14 | add_executable(1-3-1-delete 1-3-1-delete.cpp) 15 | add_executable(1-3-1-reset-count 1-3-1-reset-count.cpp) 16 | add_executable(1-3-2-cycle-shared-ptr 1-3-2-cycle-shared-ptr.cpp) 17 | add_executable(1-3-2-shared_from_this 1-3-2-shared_from_this.cpp) 18 | add_executable(1-3-2-shared_from_this2 1-3-2-shared_from_this2.cpp) 19 | add_executable(1-4-unique_ptr 1-4-unique_ptr.cpp) 20 | add_executable(1-4-unique_ptr-deleter 1-4-unique_ptr-deleter.cpp) 21 | add_executable(1-5-1-weak_ptr 1-5-1-weak_ptr.cpp) 22 | target_link_libraries(1-5-1-weak_ptr pthread) 23 | add_executable(1-5-4-misuse-weak_ptr 1-5-4-misuse-weak_ptr.cpp) 24 | add_executable(2-1-lr_value 2-1-lr_value.cpp) 25 | add_executable(2-1-mystring 2-1-mystring.cpp) 26 | add_executable(2-2-3-1-r-move 2-2-3-1-r-move.cpp) 27 | add_executable(2-2-3-2-r-move 2-2-3-2-r-move.cpp) 28 | add_executable(2-3-1-memory 2-3-1-memory.cpp) 29 | add_executable(2-3-1-memory2 2-3-1-memory2.cpp) 30 | add_executable(2-3-1-memory3 2-3-1-memory3.cpp) 31 | add_executable(2-3-2-move 2-3-2-move.cpp) 32 | add_executable(2-3-3-forward1 2-3-3-forward1.cpp) 33 | add_executable(2-3-3-forward2 2-3-3-forward2.cpp) 34 | add_executable(2-3-4-emplace_back 2-3-4-emplace_back.cpp) 35 | add_executable(2-3-4-emplace_back2 2-3-4-emplace_back2.cpp) 36 | add_executable(3-lambda 3-lambda.cpp) 37 | add_executable(4-priority_queue 4-priority_queue.cpp) 38 | add_executable(4-unordered_map 4-unordered_map.cpp) -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/time_interval.h: -------------------------------------------------------------------------------- 1 | //time_interval.h 2 | #ifndef TIME_INTERVAL_H 3 | #define TIME_INTERVAL_H 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef GCC 10 | #include 11 | #else 12 | 13 | #include 14 | 15 | #endif // GCC 16 | 17 | class TimeInterval { 18 | public: 19 | TimeInterval(const std::string &d) : detail(d) { 20 | init(); 21 | } 22 | 23 | TimeInterval() { 24 | init(); 25 | } 26 | 27 | ~TimeInterval() { 28 | #ifdef GCC 29 | gettimeofday(&end, NULL); 30 | std::cout << detail 31 | << 1000 * (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000 32 | << " ms" << endl; 33 | #else 34 | end = clock(); 35 | std::cout << detail 36 | << (double) (end - start) << " ms" << std::endl; 37 | #endif // GCC 38 | } 39 | 40 | protected: 41 | void init() { 42 | #ifdef GCC 43 | gettimeofday(&start, NULL); 44 | #else 45 | start = clock(); 46 | #endif // GCC 47 | } 48 | 49 | private: 50 | std::string detail; 51 | #ifdef GCC 52 | timeval start, end; 53 | #else 54 | clock_t start, end; 55 | #endif // GCC 56 | }; 57 | 58 | #define TIME_INTERVAL_SCOPE(d) std::shared_ptr time_interval_scope_begin = std::make_shared(d) 59 | #endif // TIME_INTERVAL_H 60 | -------------------------------------------------------------------------------- /1.3.1智能指针-move-forward-左右值引用/src1-cmake/编译说明.txt: -------------------------------------------------------------------------------- 1 | 第二节课 C++上完再统一使用cmake进行编译。 2 | 3 | 使用cmake进行编译,需要设置为c++14 4 | 5 | 步骤: 6 | 1. 进入源码目录 7 | cd src1-cmake 8 | 2. 创建build目录,并进入build目录 9 | mkdir build 10 | cd build 11 | cmake .. 12 | make 13 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/1-2-4-lock.cpp: -------------------------------------------------------------------------------- 1 | #include // std::cout 2 | #include // std::thread 3 | #include // std::mutex, std::lock_guard 4 | #include // std::logic_error 5 | 6 | std::mutex mtx; 7 | 8 | void print_even (int x) { 9 | if (x%2==0) std::cout << x << " is even\n"; 10 | else throw (std::logic_error("not even")); 11 | } 12 | 13 | void print_thread_id (int id) { 14 | try { 15 | // 这里的lock_guard换成unique_lock是一样的。 16 | // using a local lock_guard to lock mtx guarantees unlocking on destruction / exception: 17 | // std::lock_guard lck (mtx); 18 | std::unique_lock lck (mtx); 19 | print_even(id); 20 | } 21 | catch (std::logic_error&) { 22 | std::cout << "[exception caught]\n"; 23 | } 24 | } 25 | 26 | int main () 27 | { 28 | std::thread threads[10]; 29 | // spawn 10 threads: 30 | for (int i=0; i<10; ++i) 31 | threads[i] = std::thread(print_thread_id,i+1); 32 | 33 | for (auto& th : threads) th.join(); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/1-2-4-unique_lock.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | std::deque q; 9 | std::mutex mu; 10 | std::condition_variable cond; 11 | int count = 0; 12 | 13 | void fun1() { 14 | while (true) { 15 | { 16 | std::unique_lock locker(mu); // 能否换成lock_guard lock 17 | std::cout << "fun1 lock\n"; 18 | q.push_front(count++); 19 | // locker.unlock(); // 这里是不是必须的? lock_guard是没有手动释放锁的 unlock 20 | 21 | cond.notify_one(); //condition_variable 条件和Linux条件变量一样的 22 | } 23 | sleep(1); 24 | } 25 | } 26 | 27 | void fun2() { 28 | while (true) { 29 | std::unique_lock locker(mu); 30 | std::cout << "fun2 lock\n"; 31 | std::cout << "fun2 wait into\n"; 32 | cond.wait(locker, [](){return !q.empty();}); 33 | std::cout << "fun2 wait leave\n"; 34 | auto data = q.back(); 35 | q.pop_back(); 36 | // locker.unlock(); // 这里是不是必须的? 37 | std::cout << "thread2 get value form thread1: " << data << std::endl; 38 | } 39 | } 40 | int main() { 41 | std::thread t1(fun1); 42 | std::thread t2(fun2); 43 | t1.join(); 44 | t2.join(); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/1-2-mutex1.cpp: -------------------------------------------------------------------------------- 1 | //1-2-mutex1 2 | #include // std::cout 3 | #include // std::thread 4 | #include // std::mutex 5 | 6 | volatile int counter(0); // non-atomic counter 7 | std::mutex mtx; // locks access to counter 8 | 9 | void increases_10k() 10 | { 11 | for (int i=0; i<10000; ++i) { 12 | // 1. 使用try_lock的情况 13 | // if (mtx.try_lock()) { // only increase if currently not locked: 14 | // ++counter; 15 | // mtx.unlock(); 16 | // } 17 | // 2. 使用lock的情况 18 | { 19 | mtx.lock(); 20 | ++counter; 21 | mtx.unlock(); 22 | } 23 | } 24 | } 25 | 26 | int main() 27 | { 28 | std::thread threads[10]; 29 | for (int i=0; i<10; ++i) 30 | threads[i] = std::thread(increases_10k); 31 | 32 | for (auto& th : threads) th.join(); 33 | std::cout << " successful increases of the counter " << counter << std::endl; 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/1-2-mutex2-dead-lock.cpp: -------------------------------------------------------------------------------- 1 | //死锁范例1-2-mutex2-dead-lock 2 | #include 3 | #include 4 | #include 5 | 6 | struct Complex 7 | { 8 | std::mutex mutex; 9 | int i; 10 | 11 | Complex() : i(0){} 12 | 13 | void mul(int x) 14 | { 15 | std::lock_guard lock(mutex); 16 | i *= x; 17 | } 18 | 19 | void div(int x) 20 | { 21 | std::lock_guard lock(mutex); 22 | i /= x; 23 | } 24 | 25 | void both(int x, int y) 26 | { 27 | //lock_guard 构造函数加锁, 析构函数释放锁 28 | std::lock_guard lock(mutex); 29 | mul(x); // 获取不了锁 30 | div(y); 31 | } 32 | 33 | void init() 34 | { 35 | //lock_guard 构造函数加锁, 析构函数释放锁 36 | std::lock_guard lock(mutex); 37 | sub_init(); 38 | } 39 | void sub_init() 40 | { 41 | std::lock_guard lock(mutex); 42 | } 43 | }; 44 | 45 | int main(void) 46 | { 47 | Complex complex; 48 | 49 | complex.both(32, 23); 50 | std::cout << "main finish\n"; 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/1-2-recursive_mutex1.cpp: -------------------------------------------------------------------------------- 1 | //递归锁1-2-recursive_mutex1 2 | #include 3 | #include 4 | #include 5 | 6 | struct Complex 7 | { 8 | std::recursive_mutex mutex; 9 | int i; 10 | 11 | Complex() : i(0){} 12 | 13 | void mul(int x) 14 | { 15 | std::lock_guard lock(mutex); 16 | i *= x; 17 | } 18 | 19 | void div(int x) 20 | { 21 | std::unique_lock lock(mutex); 22 | 23 | 24 | i /= x; 25 | } 26 | 27 | void both(int x, int y) 28 | { 29 | std::lock_guard lock(mutex); 30 | mul(x); 31 | div(y); 32 | } 33 | }; 34 | 35 | int main(void) 36 | { 37 | Complex complex; 38 | 39 | complex.both(32, 23); //因为同一线程可以多次获取同一互斥量,不会发生死锁 40 | 41 | std::cout << "main finish\n"; 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/1-2-timed_mutex.cpp: -------------------------------------------------------------------------------- 1 | //1-2-timed_mutex 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | std::timed_mutex mutex; 8 | 9 | void work() 10 | { 11 | std::chrono::milliseconds timeout(100); 12 | 13 | while (true) 14 | { 15 | if (mutex.try_lock_for(timeout)) 16 | { 17 | std::cout << std::this_thread::get_id() << ": do work with the mutex" << std::endl; 18 | 19 | std::chrono::milliseconds sleepDuration(250); 20 | std::this_thread::sleep_for(sleepDuration); 21 | 22 | mutex.unlock(); 23 | std::this_thread::sleep_for(sleepDuration); 24 | } 25 | else 26 | { 27 | std::cout << std::this_thread::get_id() << ": do work without the mutex" << std::endl; 28 | 29 | std::chrono::milliseconds sleepDuration(100); 30 | std::this_thread::sleep_for(sleepDuration); 31 | } 32 | } 33 | } 34 | 35 | int main(void) 36 | { 37 | std::thread t1(work); 38 | std::thread t2(work); 39 | 40 | t1.join(); 41 | t2.join(); 42 | 43 | std::cout << "main finish\n"; 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/1-3-condition-sync-queue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sync_queue.h" 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | SyncQueue syncQueue(5); 9 | 10 | void PutDatas() { 11 | for (int i = 0; i < 20; ++i) { 12 | syncQueue.Put(i); 13 | } 14 | std::cout << "PutDatas finish\n"; 15 | } 16 | 17 | void TakeDatas() { 18 | int x = 0; 19 | 20 | for (int i = 0; i < 20; ++i) { 21 | syncQueue.Take(x); 22 | std::cout << x << std::endl; 23 | } 24 | std::cout << "TakeDatas finish\n"; 25 | } 26 | 27 | int main(void) { 28 | std::thread t1(PutDatas); // 生产线程 29 | std::thread t2(TakeDatas); // 消费线程 30 | 31 | t1.join(); 32 | t2.join(); 33 | 34 | std::cout << "main finish\n"; 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/1-3-condition-sync-queue2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "sync_queue2.h" 7 | 8 | using namespace std; 9 | SimpleSyncQueue syncQueue; 10 | 11 | void PutDatas() { 12 | for (int i = 0; i < 20; ++i) { 13 | syncQueue.Put(888); 14 | } 15 | } 16 | 17 | void TakeDatas() { 18 | int x = 0; 19 | 20 | for (int i = 0; i < 20; ++i) { 21 | syncQueue.Take(x); 22 | std::cout << x << std::endl; 23 | } 24 | } 25 | 26 | int main(void) { 27 | std::thread t1(PutDatas); 28 | std::thread t2(TakeDatas); 29 | 30 | t1.join(); 31 | t2.join(); 32 | 33 | std::cout << "main finish\n"; 34 | return 0; 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/1-4-atomic.cpp: -------------------------------------------------------------------------------- 1 | // atomic::load/store example 2 | #include // std::cout 3 | #include // std::atomic, std::memory_order_relaxed 4 | #include // std::thread 5 | 6 | //std::atomic count = 0;//错误初始化 7 | std::atomic count(0); // 准确初始化 8 | 9 | void set_count(int x) 10 | { 11 | std::cout << "set_count:" << x << std::endl; 12 | count.store(x, std::memory_order_relaxed); // set value atomically 13 | } 14 | 15 | void print_count() 16 | { 17 | int x; 18 | do { 19 | x = count.load(std::memory_order_relaxed); // get value atomically 20 | } while (x==0); 21 | std::cout << "count: " << x << '\n'; 22 | } 23 | 24 | int main () 25 | { 26 | std::thread t1 (print_count); 27 | std::thread t2 (set_count, 10); 28 | t1.join(); 29 | t2.join(); 30 | std::cout << "main finish\n"; 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/1-5-call_once.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | std::once_flag flag1, flag2; 6 | 7 | void simple_do_once() 8 | { 9 | std::cout << "simple_do_once\n" ; 10 | std::call_once(flag1, [](){ std::cout << "Simple example: called once\n"; }); 11 | } 12 | 13 | void may_throw_function(bool do_throw) 14 | { 15 | if (do_throw) { 16 | std::cout << "throw: call_once will retry\n"; // 17 | throw std::exception(); 18 | } 19 | std::cout << "Didn't throw, call_once will not attempt again\n"; // 保证一次 20 | } 21 | 22 | void do_once(bool do_throw) 23 | { 24 | try { 25 | std::call_once(flag2, may_throw_function, do_throw); 26 | } 27 | catch (...) { 28 | } 29 | } 30 | 31 | int main() 32 | { 33 | // std::thread st1(simple_do_once); 34 | // std::thread st2(simple_do_once); 35 | // std::thread st3(simple_do_once); 36 | // std::thread st4(simple_do_once); 37 | // st1.join(); 38 | // st2.join(); 39 | // st3.join(); 40 | // st4.join(); 41 | 42 | std::thread t1(do_once, false); 43 | std::thread t2(do_once, false); 44 | std::thread t3(do_once, false); 45 | std::thread t4(do_once, true); 46 | t1.join(); 47 | t2.join(); 48 | t3.join(); 49 | t4.join(); 50 | } 51 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/1-5-future.cpp: -------------------------------------------------------------------------------- 1 | //1-5-future 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | int find_result_to_add() 8 | { 9 | std::this_thread::sleep_for(std::chrono::seconds(5)); // 用来测试异步延迟的影响 10 | std::cout << "find_result_to_add" << std::endl; 11 | return 1 + 1; 12 | } 13 | 14 | int find_result_to_add2(int a, int b) 15 | { 16 | // std::this_thread::sleep_for(std::chrono::seconds(5)); // 用来测试异步延迟的影响 17 | return a + b; 18 | } 19 | 20 | void do_other_things() 21 | { 22 | std::cout << "do_other_things" << std::endl; 23 | // std::this_thread::sleep_for(std::chrono::seconds(5)); 24 | } 25 | 26 | int main() 27 | { 28 | // std::future std::async他是异步线程 29 | // std::future result = std::async(find_result_to_add); // 不会阻塞32行的运行 30 | // std::future result = std::async(find_result_to_add); 31 | // auto result = std::async(find_result_to_add); // 推荐的写法 32 | // do_other_things(); 33 | // std::cout << "result: " << result.get() << std::endl; // 延迟是否有影响? 34 | 35 | // std::future result2 = std::async(find_result_to_add2, 10, 20); //错误 36 | std::future result2 = std::async(find_result_to_add2, 10, 20); 37 | std::cout << "result2: " << result2.get() << std::endl; // 延迟是否有影响? 38 | //// std::cout << "main finish" << endl; 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/1-5-package_task.cpp: -------------------------------------------------------------------------------- 1 | //1-5-package_task 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | int add(int a, int b, int c) 9 | { 10 | std::cout << "call add\n"; 11 | return a + b + c; 12 | } 13 | 14 | void do_other_things() 15 | { 16 | std::cout << "do_other_things" << std::endl; 17 | } 18 | 19 | int main() 20 | { 21 | std::packaged_task task(add); // 1. 封装任务,还没有运行 22 | std::this_thread::sleep_for(std::chrono::seconds(5)); // 用来测试异步延迟的影响 23 | 24 | // do_other_things(); 25 | std::future result = task.get_future(); // 这里运行吗?这里只是获取 future 26 | // 这里才真正运行 27 | task(1, 1, 2); //必须要让任务执行,否则在get()获取future的值时会一直阻塞 28 | std::cout << "result:" << result.get() << std::endl; 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/1-5-promise.cpp: -------------------------------------------------------------------------------- 1 | //1-5-promise 2 | // std::promise和std::future配合,可以在线程之间传递数据。 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | void print1(std::promise& p) 9 | { 10 | std::cout << "print1 sleep" << std::endl; 11 | std::this_thread::sleep_for(std::chrono::seconds(1)); 12 | p.set_value("set string"); // 返回future的结果 13 | } 14 | 15 | void print2(std::promise& p) 16 | { 17 | std::cout << "print2 sleep" << std::endl; 18 | p.set_value(1); 19 | } 20 | 21 | void do_some_other_things() 22 | { 23 | std::cout << "do_some_other_things" << std::endl; 24 | } 25 | 26 | int main() 27 | { 28 | std::cout << "main1 -------------" << std::endl; 29 | std::promise promise; // 注意类型: 30 | 31 | std::future result = promise.get_future(); // future 32 | 33 | std::thread t(print1, std::ref(promise)); // 线程设置 传引用std::ref 34 | do_some_other_things(); 35 | std::cout << "wait get result" << std::endl; 36 | std::cout <<"result " << result.get() << std::endl; // 在主线程等待 promise的返回 result set string 37 | t.join(); 38 | 39 | // std::cout << "\n\nmain2 -------------" << std::endl; 40 | // std::promise promise2; 41 | 42 | // std::future result2 = promise2.get_future(); 43 | // std::thread t2(print2, std::ref(promise2)); 44 | // do_some_other_things(); 45 | // std::cout << "result2 " << result2.get() << std::endl; 46 | // t2.join(); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/1-thread.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | void threadFun(int &a) // 引用传递 6 | { 7 | cout << "this is thread fun !" < 2 | #include // 添加头文件 functional 3 | using namespace std; 4 | 5 | // function 类似c的函数指针 6 | //保存普通函数 7 | void func1(int a) 8 | { 9 | cout << a << endl; 10 | } 11 | //保存成员函数 12 | class A{ 13 | public: 14 | A(string name) : name_(name){} 15 | void func3(int i) const {cout < func1_; 35 | func1_ = func1; 36 | func1_(2); //2 37 | 38 | cout << "\n\nmain2 -----------------" << endl; 39 | //2. 保存lambda表达式 40 | std::function func2_ = [](){cout << "hello lambda" << endl;}; 41 | func2_(); //hello world 42 | 43 | cout << "\n\nmain3 -----------------" << endl; 44 | //3 保存成员函数 45 | std::function func3_ = &A::func3; 46 | A a("darren"); 47 | func3_(a, 1); 48 | 49 | //4.重载函数 50 | std::function func4_1 = std::bind((void(A::*)(int, int))&A::func4, a,std::placeholders::_1, std::placeholders::_2); 51 | func4_1(1,2); 52 | auto f_str = std::bind((void(A::*)(string))&A::func4, a,std::placeholders::_1); 53 | f_str("darren"); 54 | std::function f_str2 = std::bind((void(A::*)(string))&A::func4, &a,std::placeholders::_1); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/3-1-variable-parameter.cpp: -------------------------------------------------------------------------------- 1 | //3-1-variable-parameter 一个简单的可变模版参数函数 2 | #include 3 | 4 | using namespace std; 5 | 6 | template 7 | void f(T... args) 8 | { 9 | cout << sizeof...(args) << endl; //打印变参的个数 10 | } 11 | int main() 12 | { 13 | f(); //0 14 | f(1, 2); //2 15 | f(1, 2.5, ""); //3 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/3-1-variable-parameter2.cpp: -------------------------------------------------------------------------------- 1 | //3-1-variable-parameter2 递归函数方式展开参数包 2 | #include 3 | 4 | using namespace std; 5 | 6 | //递归终止函数 7 | void print() 8 | { 9 | cout << "empty" << endl; 10 | } 11 | //template 12 | //void print(T t) 13 | //{ 14 | // cout << t << endl; 15 | //} 16 | //展开函数 17 | template 18 | void print(T head, Args... rest) 19 | { 20 | cout << "parameter " << head << endl; 21 | print(rest...); 22 | } 23 | 24 | 25 | int main(void) 26 | { 27 | print(1,2,3,"darren", "youzi"); 28 | return 0; 29 | } 30 | 31 | //template 32 | //T sum(T t) 33 | //{ 34 | // return t; 35 | //} 36 | //template 37 | //T sum (T first, Types ... rest) 38 | //{ 39 | // return first + sum(rest...); 40 | //} 41 | //sum(1,2,3,4); //10 42 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/3-1-variable-parameter3.cpp: -------------------------------------------------------------------------------- 1 | //3-1-variable-parameter3 逗号表达式展开参数包 2 | #include 3 | 4 | using namespace std; 5 | 6 | template 7 | void printarg(T t) 8 | { 9 | cout << t << endl; 10 | } 11 | 12 | template 13 | void expand(Args... args) 14 | { 15 | int arr[] = {(printarg(args), 0)...}; 16 | } 17 | 18 | int main() 19 | { 20 | expand(1,2,3,4); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/3-1-variable-parameter4.cpp: -------------------------------------------------------------------------------- 1 | //3-1-variable-parameter4 2 | #include 3 | 4 | using namespace std; 5 | templatevoid expand(const F& f, Args&&...args) 6 | { 7 | //这里用到了完美转发 8 | initializer_list{(f(std::forward< Args>(args)),0)...}; 9 | } 10 | int main() 11 | { 12 | expand([](int i){cout< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | void MyFunc(int c) 8 | { 9 | if (c > numeric_limits< char> ::max()) 10 | throw invalid_argument("throw MyFunc argument too large."); 11 | //... 12 | } 13 | 14 | int main() 15 | { 16 | // try 17 | { 18 | MyFunc(256); //cause an exception to throw 19 | } 20 | // catch (invalid_argument& e) 21 | // { 22 | // cerr << "catch " << e.what() << endl; 23 | // return -1; 24 | // } 25 | //... 26 | cout << "end\n"; 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/5-3-exception.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class MyException:public exception{ 6 | public: 7 | const char* what()const throw(){ //throw () 表示不允许任何异常产生 8 | return "ERROR! Don't divide a number by integer zero.\n"; 9 | } 10 | }; 11 | void check(int y) throw(MyException){ //throw (MyException)表示只允许myException的异常发生 12 | if(y==0) throw MyException(); 13 | } 14 | 15 | int main() 16 | { 17 | int x=100,y=0; 18 | try{ 19 | check(y); 20 | cout< // std::cout 3 | #include // std::exception_ptr, std::current_exception, std::rethrow_exception 4 | #include // std::logic_error 5 | 6 | int main () 7 | { 8 | std::exception_ptr p; 9 | try { 10 | throw std::logic_error("some logic_error exception"); // throws 11 | } catch(const std::exception& e) { 12 | p = std::current_exception(); 13 | std::cout << "exception caught, but continuing...\n"; 14 | } 15 | 16 | std::cout << "(after exception)\n"; 17 | 18 | try { 19 | std::rethrow_exception (p); 20 | } catch (const std::exception& e) { 21 | std::cout << "exception caught: " << e.what() << '\n'; 22 | } 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/5-5-make_exception_ptr.cpp: -------------------------------------------------------------------------------- 1 | // 5-5-make_exception_ptr make_exception_ptr example 2 | #include // std::cout 3 | #include // std::make_exception_ptr, std::rethrow_exception 4 | #include // std::logic_error 5 | 6 | int main () 7 | { 8 | auto p = std::make_exception_ptr(std::logic_error("logic_error")); 9 | 10 | try { 11 | std::rethrow_exception (p); // 重新抛出异常 12 | } catch (const std::exception& e) { 13 | std::cout << "exception caught: " << e.what() << '\n'; // 捕获异常 14 | } 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/5-5-nested_exception.cpp: -------------------------------------------------------------------------------- 1 | //5-5-nested_exception nested_exception example 2 | #include // std::cerr 3 | #include // std::exception, std::throw_with_nested, std::rethrow_if_nested 4 | #include // std::logic_error 5 | 6 | // recursively print exception whats: 7 | void print_what (const std::exception& e) 8 | { 9 | std::cout << __FUNCTION__ << ", L"<< __LINE__ << ", what:" << e.what() << '\n'; 10 | try { 11 | std::rethrow_if_nested(e); 12 | } catch (const std::exception& nested) { 13 | std::cerr << "nested: "; 14 | print_what(nested); 15 | } 16 | } 17 | 18 | // throws an exception nested in another: 19 | void throw_nested() 20 | { 21 | try { 22 | throw std::logic_error ("first"); 23 | } catch (const std::exception& e) { 24 | std::throw_with_nested(std::logic_error("second")); 25 | } 26 | } 27 | 28 | int main () 29 | { 30 | try { 31 | std::cout << __FUNCTION__ << ", L"<< __LINE__ << std::endl; 32 | throw_nested(); 33 | } catch (std::exception& e) { 34 | std::cout << __FUNCTION__ << ", L"<< __LINE__ << std::endl; 35 | print_what(e); 36 | } 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/simple_sync_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_SYNC_QUEUE_H 2 | #define SIMPLE_SYNC_QUEUE_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | template 10 | class SimpleSyncQueue 11 | { 12 | public: 13 | SimpleSyncQueue(){} 14 | 15 | void Put(const T& x) 16 | { 17 | std::lock_guard locker(_mutex); 18 | _queue.push_back(x); 19 | _notEmpty.notify_one(); 20 | } 21 | 22 | void Take(T& x) 23 | { 24 | std::unique_lock locker(_mutex); 25 | _notEmpty.wait(locker, [this]{return !_queue.empty(); }); 26 | 27 | x = _queue.front(); 28 | _queue.pop_front(); 29 | } 30 | 31 | bool Empty() 32 | { 33 | std::lock_guard locker(_mutex); 34 | return _queue.empty(); 35 | } 36 | 37 | size_t Size() 38 | { 39 | std::lock_guard locker(_mutex); 40 | return _queue.size(); 41 | } 42 | 43 | private: 44 | std::list _queue; 45 | std::mutex _mutex; 46 | std::condition_variable _notEmpty; 47 | }; 48 | #endif // SIMPLE_SYNC_QUEUE_H 49 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/sync_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef SYNC_QUEUE_H 2 | #define SYNC_QUEUE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | class SyncQueue { 12 | private: 13 | bool IsFull() const { 14 | return _queue.size() == _maxSize; 15 | } 16 | 17 | bool IsEmpty() const { 18 | return _queue.empty(); 19 | } 20 | 21 | public: 22 | SyncQueue(int maxSize) : _maxSize(maxSize) { 23 | } 24 | 25 | void Put(const T &x) { 26 | std::lock_guard locker(_mutex); 27 | 28 | while (IsFull()) { 29 | std::cout << "full wait... size " << _queue.size() << std::endl; 30 | _notFull.wait(_mutex); 31 | } 32 | 33 | _queue.push_back(x); 34 | _notEmpty.notify_one(); 35 | } 36 | 37 | void Take(T &x) { 38 | std::lock_guard locker(_mutex); 39 | 40 | while (IsEmpty()) { 41 | std::cout << "empty wait.." << std::endl; 42 | _notEmpty.wait(_mutex); 43 | } 44 | 45 | x = _queue.front(); 46 | _queue.pop_front(); 47 | _notFull.notify_one(); 48 | } 49 | 50 | bool Empty() { 51 | std::lock_guard locker(_mutex); 52 | return _queue.empty(); 53 | } 54 | 55 | bool Full() { 56 | std::lock_guard locker(_mutex); 57 | return _queue.size() == _maxSize; 58 | } 59 | 60 | size_t Size() { 61 | std::lock_guard locker(_mutex); 62 | return _queue.size(); 63 | } 64 | 65 | int Count() { 66 | return _queue.size(); 67 | } 68 | 69 | private: 70 | std::list _queue; //缓冲区 71 | std::mutex _mutex; //互斥量和条件变量结合起来使用 72 | std::condition_variable_any _notEmpty;//不为空的条件变量 73 | std::condition_variable_any _notFull; //没有满的条件变量 74 | int _maxSize; //同步队列最大的size 75 | }; 76 | 77 | #endif // SYNC_QUEUE_H 78 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/sync_queue2.h: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_SYNC_QUEUE_H 2 | #define SIMPLE_SYNC_QUEUE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | class SimpleSyncQueue { 12 | public: 13 | SimpleSyncQueue() {} 14 | 15 | void Put(const T &x) { 16 | std::lock_guard locker(_mutex); 17 | _queue.push_back(x); 18 | _notEmpty.notify_one(); 19 | } 20 | 21 | void Take(T &x) { 22 | std::unique_lock locker(_mutex); 23 | _notEmpty.wait(locker, [this] { return !_queue.empty(); }); 24 | 25 | x = _queue.front(); 26 | _queue.pop_front(); 27 | } 28 | 29 | bool Empty() { 30 | std::lock_guard locker(_mutex); 31 | return _queue.empty(); 32 | } 33 | 34 | size_t Size() { 35 | std::lock_guard locker(_mutex); 36 | return _queue.size(); 37 | } 38 | 39 | private: 40 | std::list _queue; 41 | std::mutex _mutex; 42 | std::condition_variable _notEmpty; 43 | }; 44 | 45 | #endif // SIMPLE_SYNC_QUEUE_H 46 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/zero_thread.cpp: -------------------------------------------------------------------------------- 1 | #include "zero_thread.h" 2 | #include 3 | #include 4 | #include 5 | 6 | ZERO_Thread::ZERO_Thread() : 7 | running_(false), th_(NULL) { 8 | 9 | } 10 | 11 | ZERO_Thread::~ZERO_Thread() { 12 | if (th_ != NULL) { 13 | //如果到调用析构函数的时候,调用者还没有调用join则触发detach,此时是一个比较危险的动作,用户必须知道他在做什么 14 | if (th_->joinable()) { 15 | std::cout << "~ZERO_Thread detach\n"; 16 | th_->detach(); 17 | } 18 | 19 | delete th_; 20 | th_ = NULL; 21 | } 22 | std::cout << "~ZERO_Thread()" << std::endl; 23 | } 24 | 25 | bool ZERO_Thread::start() { 26 | if (running_) { 27 | return false; 28 | } 29 | try { 30 | th_ = new std::thread(&ZERO_Thread::threadEntry, this); 31 | } 32 | catch (...) { 33 | throw "[ZERO_Thread::start] thread start error"; 34 | } 35 | return true; 36 | } 37 | 38 | void ZERO_Thread::stop() { 39 | running_ = false; 40 | } 41 | 42 | bool ZERO_Thread::isAlive() const { 43 | return running_; 44 | } 45 | 46 | void ZERO_Thread::join() { 47 | if (th_->joinable()) { 48 | th_->join(); // 不是detach才去join 49 | } 50 | } 51 | 52 | void ZERO_Thread::detach() { 53 | th_->detach(); 54 | } 55 | 56 | size_t ZERO_Thread::CURRENT_THREADID() { 57 | // 声明为thread_local的本地变量在线程中是持续存在的,不同于普通临时变量的生命周期, 58 | // 它具有static变量一样的初始化特征和生命周期,即使它不被声明为static。 59 | static thread_local size_t 60 | threadId = 0; 61 | if (threadId == 0) { 62 | std::stringstream ss; 63 | ss << std::this_thread::get_id(); 64 | threadId = strtol(ss.str().c_str(), NULL, 0); 65 | } 66 | return threadId; 67 | } 68 | 69 | void ZERO_Thread::threadEntry() { 70 | running_ = true; 71 | 72 | try { 73 | run(); // 函数运行所在 调用子类的run函数 74 | } 75 | catch (std::exception &ex) { 76 | running_ = false; 77 | throw ex; 78 | } 79 | catch (...) { 80 | running_ = false; 81 | throw; 82 | } 83 | running_ = false; 84 | } 85 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/zero_thread.h: -------------------------------------------------------------------------------- 1 | #ifndef ZERO_THREAD_H 2 | #define ZERO_THREAD_H 3 | 4 | #include 5 | 6 | class ZERO_Thread { 7 | public: 8 | ZERO_Thread(); // 构造函数 9 | virtual ~ZERO_Thread(); // 析构函数 10 | bool start(); 11 | 12 | void stop(); 13 | 14 | bool isAlive() const; // 线程是否存活. 15 | std::thread::id id() { return th_->get_id(); } 16 | 17 | std::thread *getThread() { return th_; } 18 | 19 | void join(); // 等待当前线程结束, 不能在当前线程上调用 20 | void detach(); //能在当前线程上调用 21 | static size_t CURRENT_THREADID(); 22 | 23 | protected: 24 | void threadEntry(); 25 | 26 | virtual void run() = 0; // 运行 27 | protected: 28 | bool running_; //是否在运行 29 | std::thread *th_; 30 | }; 31 | 32 | #endif // ZERO_THREAD_H 33 | -------------------------------------------------------------------------------- /1.3.2C++11多线程thread-互斥量-条件变量-原子变量/说明.txt: -------------------------------------------------------------------------------- 1 | 第二节课 C++上完再统一使用cmake进行编译。 2 | 3 | 使用cmake进行编译,需要设置为c++14 4 | 5 | 步骤: 6 | 1. 进入源码目录 7 | cd src2-cmake 8 | 2. 创建build目录,并进入build目录 9 | mkdir build 10 | cd build 11 | cmake .. 12 | make 13 | -------------------------------------------------------------------------------- /2.3.1NtyCo/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | out 4 | gen 5 | .git 6 | .github 7 | cmake-build-debug -------------------------------------------------------------------------------- /2.3.1NtyCo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | project(NtyCo) 4 | 5 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) 6 | 7 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) 8 | 9 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) 10 | 11 | include_directories( 12 | core 13 | ) 14 | 15 | 16 | # 第三方库 17 | set(LIBS crypto pthread ssl) 18 | 19 | subdirs( 20 | core 21 | sample 22 | ) 23 | -------------------------------------------------------------------------------- /2.3.1NtyCo/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CC = gcc 3 | ECHO = echo 4 | 5 | SUB_DIR = core/ sample/ 6 | ROOT_DIR = $(shell pwd) 7 | OBJS_DIR = $(ROOT_DIR)/objs 8 | BIN_DIR = $(ROOT_DIR)/bin 9 | 10 | BIN = nty_server nty_client mul_port_client_epoll 11 | FLAG = -lpthread -O3 -lcrypto -lssl -I $(ROOT_DIR)/core 12 | 13 | CUR_SOURCE = ${wildcard *.c} 14 | CUR_OBJS = ${patsubst %.c, %.o, %(CUR_SOURCE)} 15 | 16 | export CC BIN_DIR OBJS_DIR ROOT_IDR FLAG BIN ECHO EFLAG 17 | 18 | all : $(SUB_DIR) $(BIN) 19 | .PHONY : all 20 | 21 | 22 | $(SUB_DIR) : ECHO 23 | make -C $@ 24 | 25 | #DEBUG : ECHO 26 | # make -C bin 27 | 28 | ECHO : 29 | @echo $(SUB_DIR) 30 | 31 | 32 | nty_server : $(OBJS_DIR)/nty_socket.o $(OBJS_DIR)/nty_coroutine.o $(OBJS_DIR)/nty_epoll.o $(OBJS_DIR)/nty_schedule.o $(OBJS_DIR)/nty_server.o 33 | $(CC) -o $(BIN_DIR)/$@ $^ $(FLAG) 34 | 35 | nty_client : $(OBJS_DIR)/nty_socket.o $(OBJS_DIR)/nty_coroutine.o $(OBJS_DIR)/nty_epoll.o $(OBJS_DIR)/nty_schedule.o $(OBJS_DIR)/nty_client.o 36 | $(CC) -o $(BIN_DIR)/$@ $^ $(FLAG) 37 | 38 | mul_port_client_epoll : $(OBJS_DIR)/nty_socket.o $(OBJS_DIR)/nty_coroutine.o $(OBJS_DIR)/nty_epoll.o $(OBJS_DIR)/nty_schedule.o $(OBJS_DIR)/mul_port_client_epoll.o 39 | $(CC) -o $(BIN_DIR)/$@ $^ $(FLAG) 40 | 41 | clean : 42 | rm -rf $(BIN_DIR)/* $(OBJS_DIR)/* 43 | 44 | -------------------------------------------------------------------------------- /2.3.1NtyCo/core/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | aux_source_directory(. SRC) 2 | 3 | add_library(nty_core ${SRC}) 4 | -------------------------------------------------------------------------------- /2.3.1NtyCo/core/Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | CUR_SOURCE = ${wildcard *.c} 4 | 5 | CUR_OBJS = ${patsubst %.c, %.o, $(CUR_SOURCE)} 6 | 7 | all : $(SUB_DIR) $(CUR_OBJS) 8 | 9 | $(SUB_DIR) : ECHO 10 | make -C $@ 11 | 12 | $(CUR_OBJS) : %.o : %.c 13 | $(CC) -c $^ -o $(OBJS_DIR)/$@ $(FLAG) 14 | 15 | ECHO : 16 | @echo $(SUB_DIR) 17 | -------------------------------------------------------------------------------- /2.3.1NtyCo/core/nty_epoll.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 68725 on 2022/7/14. 3 | // 4 | #include 5 | #include "nty_coroutine.h" 6 | 7 | // 创建epoll 8 | int nty_epoller_create(void) { 9 | return epoll_create(1024); 10 | } 11 | // epoll_wait包装 12 | int nty_epoller_wait(struct timespec t) { 13 | nty_schedule *sched = nty_coroutine_get_sched(); 14 | return epoll_wait(sched->epfd, sched->eventlist, NTY_CO_MAX_EVENTS, t.tv_sec * 1000.0 + t.tv_nsec / 1000000.0); 15 | } 16 | //多线程做准备 17 | int nty_epoller_ev_register_trigger(void) { 18 | nty_schedule *sched = nty_coroutine_get_sched(); 19 | if (!sched->eventfd) { 20 | sched->eventfd = eventfd(0, EFD_NONBLOCK); 21 | assert(sched->eventfd != -1); 22 | } 23 | 24 | struct epoll_event ev; 25 | ev.events = EPOLLIN; 26 | ev.data.fd = sched->eventfd; 27 | int ret = epoll_ctl(sched->epfd, EPOLL_CTL_ADD, sched->eventfd, &ev); 28 | assert(ret != -1); 29 | } 30 | -------------------------------------------------------------------------------- /2.3.1NtyCo/sample/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | aux_source_directory(. SRC) 3 | 4 | # 编译不过的,先放这里 5 | set(NOT_COMPILE ) 6 | 7 | foreach(FILE_PATH ${SRC}) 8 | string(REGEX REPLACE ".+/(.+)\\..*" "\\1" FILE_NAME ${FILE_PATH}) 9 | list(FIND NOT_COMPILE ${FILE_NAME} RESULT) 10 | if(${RESULT} EQUAL -1) 11 | message(${FILE_NAME}) 12 | add_executable(${FILE_NAME} ${FILE_PATH}) 13 | target_link_libraries(${FILE_NAME} nty_core ${LIBS}) 14 | endif() 15 | endforeach() 16 | -------------------------------------------------------------------------------- /2.3.1NtyCo/sample/Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | CUR_SOURCE = ${wildcard *.c} 4 | 5 | CUR_OBJS = ${patsubst %.c, %.o, $(CUR_SOURCE)} 6 | 7 | all : $(SUB_DIR) $(CUR_OBJS) 8 | 9 | $(SUB_DIR) : ECHO 10 | make -C $@ 11 | 12 | $(CUR_OBJS) : %.o : %.c 13 | $(CC) -c $^ -o $(OBJS_DIR)/$@ $(FLAG) 14 | 15 | ECHO : 16 | @echo $(SUB_DIR) 17 | -------------------------------------------------------------------------------- /2.3.1NtyCo/sample/nty_client.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 68725 on 2022/7/16. 3 | // 4 | #include "nty_coroutine.h" 5 | #include 6 | 7 | #define NTY_SERVER_IPADDR "192.168.109.100" 8 | #define NTY_SERVER_PORT 8080 9 | 10 | int init_client(void) { 11 | int clientfd = nty_socket(AF_INET, SOCK_STREAM, 0); 12 | if (clientfd <= 0) { 13 | printf("socket failed\n"); 14 | return -1; 15 | } 16 | struct sockaddr_in serveraddr = {0}; 17 | serveraddr.sin_family = AF_INET; 18 | serveraddr.sin_port = htons(NTY_SERVER_PORT); 19 | serveraddr.sin_addr.s_addr = inet_addr(NTY_SERVER_IPADDR); 20 | 21 | int result = nty_connect(clientfd, (struct sockaddr *) &serveraddr, sizeof(serveraddr)); 22 | if (result != 0) { 23 | printf("connect failed\n"); 24 | return -2; 25 | } 26 | return clientfd; 27 | } 28 | 29 | void client(void *arg) { 30 | int clientfd = init_client(); 31 | char *buffer = "ntyco_client\r\n"; 32 | while (1) { 33 | int length = nty_send(clientfd, buffer, strlen(buffer), 0); 34 | printf("echo length : %d\n", length); 35 | sleep(1); 36 | } 37 | } 38 | 39 | int main(int argc, char *argv[]) { 40 | nty_coroutine *co = NULL; 41 | nty_coroutine_create(&co, client, NULL); 42 | nty_schedule_run(); //run 43 | return 0; 44 | } 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /2.3.1NtyCo/sample/nty_server.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 68725 on 2022/7/15. 3 | // 4 | #include 5 | #include "nty_coroutine.h" 6 | #include 7 | #include 8 | #include 9 | 10 | #define MAX_CLIENT_NUM 1000000 11 | #define TIME_SUB_MS(tv1, tv2) ((tv1.tv_sec - tv2.tv_sec) * 1000 + (tv1.tv_usec - tv2.tv_usec) / 1000) 12 | 13 | void server_reader(void *arg) { 14 | int fd = *(int *) arg; 15 | int ret = 0; 16 | 17 | struct pollfd fds; 18 | fds.fd = fd; 19 | fds.events = POLLIN; 20 | while (1) { 21 | char buf[1024] = {0}; 22 | ret = nty_recv(fd, buf, 1024, 0); 23 | if (ret > 0) { 24 | if (fd > MAX_CLIENT_NUM) { 25 | printf("100w connect\n"); 26 | assert(0); 27 | } 28 | ret = nty_send(fd, buf, strlen(buf), 0); 29 | if (ret == -1) { 30 | nty_close(fd); 31 | break; 32 | } 33 | } 34 | else if (ret == 0) { 35 | nty_close(fd); 36 | break; 37 | } 38 | } 39 | } 40 | 41 | void server(void *arg) { 42 | unsigned short port = *(unsigned short *) arg; 43 | free(arg); 44 | int fd = nty_socket(AF_INET, SOCK_STREAM, 0); 45 | if (fd < 0) return; 46 | 47 | struct sockaddr_in local, remote; 48 | local.sin_family = AF_INET; 49 | local.sin_port = htons(port); 50 | local.sin_addr.s_addr = INADDR_ANY; 51 | bind(fd, (struct sockaddr *) &local, sizeof(struct sockaddr_in)); 52 | listen(fd, 128); 53 | printf("listen port : %d\n", port); 54 | 55 | struct timeval tv_begin; 56 | gettimeofday(&tv_begin, NULL); 57 | 58 | while (1) { 59 | socklen_t len = sizeof(struct sockaddr_in); 60 | int cli_fd = nty_accept(fd, (struct sockaddr *) &remote, &len); 61 | if (cli_fd % 1000 == 999) { 62 | 63 | struct timeval tv_cur; 64 | memcpy(&tv_cur, &tv_begin, sizeof(struct timeval)); 65 | 66 | gettimeofday(&tv_begin, NULL); 67 | int time_used = TIME_SUB_MS(tv_begin, tv_cur); 68 | 69 | printf("client fd : %d, time_used: %d\n", cli_fd, time_used); 70 | } 71 | nty_coroutine *read_co; 72 | nty_coroutine_create(&read_co, server_reader, &cli_fd); 73 | } 74 | } 75 | 76 | 77 | int main(int argc, char *argv[]) { 78 | nty_coroutine *co = NULL; 79 | int i = 0; 80 | unsigned short base_port = 8080; 81 | for (i = 0; i < 100; i++) { 82 | unsigned short *port = calloc(1, sizeof(unsigned short)); 83 | *port = base_port + i; 84 | nty_coroutine_create(&co, server, port); 85 | } 86 | nty_schedule_run(); //run 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | PROJECT(test_curd) 3 | 4 | SET(SRC_LIST 5 | DBPool.cpp IMUser.cpp 6 | ) 7 | 8 | SET(EXECUTABLE_OUTPUT_PATH ./) 9 | 10 | 11 | ADD_DEFINITIONS(-g -W -Wall -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DAC_HAS_INFO 12 | -DAC_HAS_WARNING -DAC_HAS_ERROR -DAC_HAS_CRITICAL -DTIXML_USE_STL 13 | -DAC_HAS_DEBUG -DLINUX_DAEMON -std=c++11 -DENCRYPT) 14 | 15 | INCLUDE_DIRECTORIES(./) 16 | # 注意自己的库路径 17 | INCLUDE_DIRECTORIES(/usr/include/mysql) 18 | LINK_DIRECTORIES(/usr/lib/x86_64-linux-gnu/ /usr/lib64/mysql) 19 | 20 | ADD_EXECUTABLE(test_curd test_curd.cpp ${SRC_LIST}) 21 | ADD_EXECUTABLE(test_dbpool test_dbpool.cpp ZeroThreadpool.cpp ${SRC_LIST}) 22 | 23 | 24 | TARGET_LINK_LIBRARIES(test_curd mysqlclient pthread) 25 | TARGET_LINK_LIBRARIES(test_dbpool mysqlclient pthread) -------------------------------------------------------------------------------- /3.1.4连接池connpoll/IMUser.h: -------------------------------------------------------------------------------- 1 | #ifndef IMUSER_H_ 2 | #define IMUSER_H_ 3 | 4 | #include 5 | #include 6 | #include "DBpool.h" 7 | 8 | #define DROP_IMUSER_TABLE "DROP TABLE IF EXISTS IMUser" /* if EXISTS 好处 是如果表不存在,执行不会报错 */ 9 | 10 | 11 | #define CREATE_IMUSER_TABLE "CREATE TABLE IMUser ( \ 12 | `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id', \ 13 | `sex` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '1男2女0未知', \ 14 | `name` varchar(32) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '用户名', \ 15 | `domain` varchar(32) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '拼音', \ 16 | `nick` varchar(32) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '花名,绰号等', \ 17 | `password` varchar(32) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '密码', \ 18 | `salt` varchar(4) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '混淆码', \ 19 | `phone` varchar(11) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '手机号码', \ 20 | `email` varchar(64) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT 'email', \ 21 | `company` varchar(64) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '公司名称', \ 22 | `address` varchar(64) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '所在地区', \ 23 | `avatar` varchar(255) COLLATE utf8mb4_bin DEFAULT '' COMMENT '自定义用户头像', \ 24 | `validateMethod` tinyint(2) unsigned DEFAULT '1' COMMENT '好友验证方式', \ 25 | `departId` int(11) unsigned NOT NULL DEFAULT '1' COMMENT '所属部门Id', \ 26 | `status` tinyint(2) unsigned DEFAULT '0' COMMENT '1. 试用期 2. 正式 3. 离职 4.实习', \ 27 | `created` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间', \ 28 | `updated` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间', \ 29 | `push_shield_status` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '0关闭勿扰 1开启勿扰', \ 30 | `sign_info` varchar(128) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '个性签名', \ 31 | PRIMARY KEY (`id`), \ 32 | KEY `idx_domain` (`domain`), \ 33 | KEY `idx_name` (`name`), \ 34 | KEY `idx_phone` (`phone`) \ 35 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;" 36 | 37 | #define INSERT_SAMPLE "INSERT INTO user(name,email,phone) VALUES(?,?,?)" 38 | #define SELECT_SAMPLE "SELECT name,email,phone FROM user" 39 | 40 | //1.创建数据库mysql_pool_test: create database mysql_pool_test; 41 | // show databases; 查看数据库 42 | // show tables; 查看有哪些表 43 | // desc table_name; 查看表结构 44 | // 45 | 46 | std::string int2string(uint32_t user_id); // 只是一个工具函数 47 | bool insertUser(CDBConn *pDBConn, int id); 48 | 49 | #endif -------------------------------------------------------------------------------- /3.1.4连接池connpoll/README.md: -------------------------------------------------------------------------------- 1 | mysql连接池 -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/3.21.3/CMakeDetermineCompilerABI_C.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.1.4连接池connpoll/build/CMakeFiles/3.21.3/CMakeDetermineCompilerABI_C.bin -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/3.21.3/CMakeDetermineCompilerABI_CXX.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.1.4连接池connpoll/build/CMakeFiles/3.21.3/CMakeDetermineCompilerABI_CXX.bin -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/3.21.3/CMakeSystem.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_HOST_SYSTEM "Linux-4.15.0-142-generic") 2 | set(CMAKE_HOST_SYSTEM_NAME "Linux") 3 | set(CMAKE_HOST_SYSTEM_VERSION "4.15.0-142-generic") 4 | set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64") 5 | 6 | 7 | set(CMAKE_SYSTEM "Linux-4.15.0-142-generic") 8 | set(CMAKE_SYSTEM_NAME "Linux") 9 | set(CMAKE_SYSTEM_VERSION "4.15.0-142-generic") 10 | set(CMAKE_SYSTEM_PROCESSOR "x86_64") 11 | 12 | set(CMAKE_CROSSCOMPILING "FALSE") 13 | 14 | set(CMAKE_SYSTEM_LOADED 1) 15 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/3.21.3/CompilerIdC/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.1.4连接池connpoll/build/CMakeFiles/3.21.3/CompilerIdC/a.out -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/3.21.3/CompilerIdCXX/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.1.4连接池connpoll/build/CMakeFiles/3.21.3/CompilerIdCXX/a.out -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/CMakeDirectoryInformation.cmake: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 3.21 3 | 4 | # Relative path conversion top directories. 5 | set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/mnt/hgfs/pool/src/mysql_pool") 6 | set(CMAKE_RELATIVE_PATH_TOP_BINARY "/mnt/hgfs/pool/src/mysql_pool/build") 7 | 8 | # Force unix paths in dependencies. 9 | set(CMAKE_FORCE_UNIX_PATHS 1) 10 | 11 | 12 | # The C and CXX include file regular expressions for this directory. 13 | set(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") 14 | set(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") 15 | set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) 16 | set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) 17 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/TargetDirectories.txt: -------------------------------------------------------------------------------- 1 | /mnt/hgfs/pool/src/mysql_pool/build/CMakeFiles/rebuild_cache.dir 2 | /mnt/hgfs/pool/src/mysql_pool/build/CMakeFiles/edit_cache.dir 3 | /mnt/hgfs/pool/src/mysql_pool/build/CMakeFiles/test_dbpool.dir 4 | /mnt/hgfs/pool/src/mysql_pool/build/CMakeFiles/test_curd.dir 5 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/cmake.check_cache: -------------------------------------------------------------------------------- 1 | # This file is generated by cmake for dependency checking of the CMakeCache.txt file 2 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/progress.marks: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_curd.dir/DBPool.cpp.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.1.4连接池connpoll/build/CMakeFiles/test_curd.dir/DBPool.cpp.o -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_curd.dir/DependInfo.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Consider dependencies only in project. 3 | set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) 4 | 5 | # The set of languages for which implicit dependencies are needed: 6 | set(CMAKE_DEPENDS_LANGUAGES 7 | ) 8 | 9 | # The set of dependency files which are needed: 10 | set(CMAKE_DEPENDS_DEPENDENCY_FILES 11 | "/mnt/hgfs/pool/src/mysql_pool/DBPool.cpp" "CMakeFiles/test_curd.dir/DBPool.cpp.o" "gcc" "CMakeFiles/test_curd.dir/DBPool.cpp.o.d" 12 | "/mnt/hgfs/pool/src/mysql_pool/IMUser.cpp" "CMakeFiles/test_curd.dir/IMUser.cpp.o" "gcc" "CMakeFiles/test_curd.dir/IMUser.cpp.o.d" 13 | "/mnt/hgfs/pool/src/mysql_pool/test_curd.cpp" "CMakeFiles/test_curd.dir/test_curd.cpp.o" "gcc" "CMakeFiles/test_curd.dir/test_curd.cpp.o.d" 14 | ) 15 | 16 | # Targets to which this target links. 17 | set(CMAKE_TARGET_LINKED_INFO_FILES 18 | ) 19 | 20 | # Fortran module output directory. 21 | set(CMAKE_Fortran_TARGET_MODULE_DIR "") 22 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_curd.dir/IMUser.cpp.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.1.4连接池connpoll/build/CMakeFiles/test_curd.dir/IMUser.cpp.o -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_curd.dir/cmake_clean.cmake: -------------------------------------------------------------------------------- 1 | file(REMOVE_RECURSE 2 | "CMakeFiles/test_curd.dir/DBPool.cpp.o" 3 | "CMakeFiles/test_curd.dir/DBPool.cpp.o.d" 4 | "CMakeFiles/test_curd.dir/IMUser.cpp.o" 5 | "CMakeFiles/test_curd.dir/IMUser.cpp.o.d" 6 | "CMakeFiles/test_curd.dir/test_curd.cpp.o" 7 | "CMakeFiles/test_curd.dir/test_curd.cpp.o.d" 8 | "test_curd" 9 | "test_curd.pdb" 10 | ) 11 | 12 | # Per-language clean rules from dependency scanning. 13 | foreach (lang CXX) 14 | include(CMakeFiles/test_curd.dir/cmake_clean_${lang}.cmake OPTIONAL) 15 | endforeach () 16 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_curd.dir/compiler_depend.ts: -------------------------------------------------------------------------------- 1 | # 2 | CMAKE 3 | generated 4 | file: DO 5 | NOT 6 | EDIT! 7 | # 8 | Timestamp 9 | file 10 | for compiler generated 11 | dependencies 12 | management 13 | for test_curd. 14 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_curd.dir/depend.make: -------------------------------------------------------------------------------- 1 | # Empty dependencies file for test_curd. 2 | # This may be replaced when dependencies are built. 3 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_curd.dir/flags.make: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 3.21 3 | 4 | # compile CXX with /usr/local/gcc-11.2/bin/g++-11.2 5 | CXX_DEFINES = -DAC_HAS_CRITICAL -DAC_HAS_DEBUG -DAC_HAS_ERROR -DAC_HAS_INFO -DAC_HAS_WARNING -DENCRYPT -DLINUX_DAEMON -DTIXML_USE_STL -D_FILE_OFFSET_BITS=64 -D_REENTRANT 6 | 7 | CXX_INCLUDES = -I/mnt/hgfs/pool/src/mysql_pool/. -I/usr/include/mysql 8 | 9 | CXX_FLAGS = -g -W -Wall -std=c++11 10 | 11 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_curd.dir/link.txt: -------------------------------------------------------------------------------- 1 | /usr/local/gcc-11.2/bin/g++-11.2 -rdynamic CMakeFiles/test_curd.dir/test_curd.cpp.o CMakeFiles/test_curd.dir/DBPool.cpp.o CMakeFiles/test_curd.dir/IMUser.cpp.o -o test_curd -L/usr/lib64/mysql -Wl,-rpath,/usr/lib64/mysql -lmysqlclient -lpthread 2 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_curd.dir/progress.make: -------------------------------------------------------------------------------- 1 | CMAKE_PROGRESS_1 = 1 2 | CMAKE_PROGRESS_2 = 2 3 | CMAKE_PROGRESS_3 = 3 4 | CMAKE_PROGRESS_4 = 4 5 | 6 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_curd.dir/test_curd.cpp.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.1.4连接池connpoll/build/CMakeFiles/test_curd.dir/test_curd.cpp.o -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/DBPool.cpp.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/DBPool.cpp.o -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/DependInfo.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Consider dependencies only in project. 3 | set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) 4 | 5 | # The set of languages for which implicit dependencies are needed: 6 | set(CMAKE_DEPENDS_LANGUAGES 7 | ) 8 | 9 | # The set of dependency files which are needed: 10 | set(CMAKE_DEPENDS_DEPENDENCY_FILES 11 | "/mnt/hgfs/pool/src/mysql_pool/DBPool.cpp" "CMakeFiles/test_dbpool.dir/DBPool.cpp.o" "gcc" "CMakeFiles/test_dbpool.dir/DBPool.cpp.o.d" 12 | "/mnt/hgfs/pool/src/mysql_pool/IMUser.cpp" "CMakeFiles/test_dbpool.dir/IMUser.cpp.o" "gcc" "CMakeFiles/test_dbpool.dir/IMUser.cpp.o.d" 13 | "/mnt/hgfs/pool/src/mysql_pool/ZeroThreadpool.cpp" "CMakeFiles/test_dbpool.dir/ZeroThreadpool.cpp.o" "gcc" "CMakeFiles/test_dbpool.dir/ZeroThreadpool.cpp.o.d" 14 | "/mnt/hgfs/pool/src/mysql_pool/test_dbpool.cpp" "CMakeFiles/test_dbpool.dir/test_dbpool.cpp.o" "gcc" "CMakeFiles/test_dbpool.dir/test_dbpool.cpp.o.d" 15 | ) 16 | 17 | # Targets to which this target links. 18 | set(CMAKE_TARGET_LINKED_INFO_FILES 19 | ) 20 | 21 | # Fortran module output directory. 22 | set(CMAKE_Fortran_TARGET_MODULE_DIR "") 23 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/IMUser.cpp.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/IMUser.cpp.o -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/ZeroThreadpool.cpp.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/ZeroThreadpool.cpp.o -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/cmake_clean.cmake: -------------------------------------------------------------------------------- 1 | file(REMOVE_RECURSE 2 | "CMakeFiles/test_dbpool.dir/DBPool.cpp.o" 3 | "CMakeFiles/test_dbpool.dir/DBPool.cpp.o.d" 4 | "CMakeFiles/test_dbpool.dir/IMUser.cpp.o" 5 | "CMakeFiles/test_dbpool.dir/IMUser.cpp.o.d" 6 | "CMakeFiles/test_dbpool.dir/ZeroThreadpool.cpp.o" 7 | "CMakeFiles/test_dbpool.dir/ZeroThreadpool.cpp.o.d" 8 | "CMakeFiles/test_dbpool.dir/test_dbpool.cpp.o" 9 | "CMakeFiles/test_dbpool.dir/test_dbpool.cpp.o.d" 10 | "test_dbpool" 11 | "test_dbpool.pdb" 12 | ) 13 | 14 | # Per-language clean rules from dependency scanning. 15 | foreach (lang CXX) 16 | include(CMakeFiles/test_dbpool.dir/cmake_clean_${lang}.cmake OPTIONAL) 17 | endforeach () 18 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/compiler_depend.ts: -------------------------------------------------------------------------------- 1 | # 2 | CMAKE 3 | generated 4 | file: DO 5 | NOT 6 | EDIT! 7 | # 8 | Timestamp 9 | file 10 | for compiler generated 11 | dependencies 12 | management 13 | for test_dbpool. 14 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/depend.make: -------------------------------------------------------------------------------- 1 | # Empty dependencies file for test_dbpool. 2 | # This may be replaced when dependencies are built. 3 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/flags.make: -------------------------------------------------------------------------------- 1 | # CMAKE generated file: DO NOT EDIT! 2 | # Generated by "Unix Makefiles" Generator, CMake Version 3.21 3 | 4 | # compile CXX with /usr/local/gcc-11.2/bin/g++-11.2 5 | CXX_DEFINES = -DAC_HAS_CRITICAL -DAC_HAS_DEBUG -DAC_HAS_ERROR -DAC_HAS_INFO -DAC_HAS_WARNING -DENCRYPT -DLINUX_DAEMON -DTIXML_USE_STL -D_FILE_OFFSET_BITS=64 -D_REENTRANT 6 | 7 | CXX_INCLUDES = -I/mnt/hgfs/pool/src/mysql_pool/. -I/usr/include/mysql 8 | 9 | CXX_FLAGS = -g -W -Wall -std=c++11 10 | 11 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/link.txt: -------------------------------------------------------------------------------- 1 | /usr/local/gcc-11.2/bin/g++-11.2 -rdynamic CMakeFiles/test_dbpool.dir/test_dbpool.cpp.o CMakeFiles/test_dbpool.dir/ZeroThreadpool.cpp.o CMakeFiles/test_dbpool.dir/DBPool.cpp.o CMakeFiles/test_dbpool.dir/IMUser.cpp.o -o test_dbpool -L/usr/lib64/mysql -Wl,-rpath,/usr/lib64/mysql -lmysqlclient -lpthread 2 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/progress.make: -------------------------------------------------------------------------------- 1 | CMAKE_PROGRESS_1 = 5 2 | CMAKE_PROGRESS_2 = 6 3 | CMAKE_PROGRESS_3 = 7 4 | CMAKE_PROGRESS_4 = 8 5 | CMAKE_PROGRESS_5 = 9 6 | 7 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/test_dbpool.cpp.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.1.4连接池connpoll/build/CMakeFiles/test_dbpool.dir/test_dbpool.cpp.o -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/cmake_install.cmake: -------------------------------------------------------------------------------- 1 | # Install script for directory: /mnt/hgfs/pool/src/mysql_pool 2 | 3 | # Set the install prefix 4 | if (NOT DEFINED CMAKE_INSTALL_PREFIX) 5 | set(CMAKE_INSTALL_PREFIX "/usr/local") 6 | endif () 7 | string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") 8 | 9 | # Set the install configuration name. 10 | if (NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) 11 | if (BUILD_TYPE) 12 | string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" 13 | CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") 14 | else () 15 | set(CMAKE_INSTALL_CONFIG_NAME "") 16 | endif () 17 | message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") 18 | endif () 19 | 20 | # Set the component getting installed. 21 | if (NOT CMAKE_INSTALL_COMPONENT) 22 | if (COMPONENT) 23 | message(STATUS "Install component: \"${COMPONENT}\"") 24 | set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") 25 | else () 26 | set(CMAKE_INSTALL_COMPONENT) 27 | endif () 28 | endif () 29 | 30 | # Install shared libraries without execute permission? 31 | if (NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) 32 | set(CMAKE_INSTALL_SO_NO_EXE "1") 33 | endif () 34 | 35 | # Is this installation the result of a crosscompile? 36 | if (NOT DEFINED CMAKE_CROSSCOMPILING) 37 | set(CMAKE_CROSSCOMPILING "FALSE") 38 | endif () 39 | 40 | # Set default install directory permissions. 41 | if (NOT DEFINED CMAKE_OBJDUMP) 42 | set(CMAKE_OBJDUMP "/usr/bin/objdump") 43 | endif () 44 | 45 | if (CMAKE_INSTALL_COMPONENT) 46 | set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt") 47 | else () 48 | set(CMAKE_INSTALL_MANIFEST "install_manifest.txt") 49 | endif () 50 | 51 | string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT 52 | "${CMAKE_INSTALL_MANIFEST_FILES}") 53 | file(WRITE "/mnt/hgfs/pool/src/mysql_pool/build/${CMAKE_INSTALL_MANIFEST}" 54 | "${CMAKE_INSTALL_MANIFEST_CONTENT}") 55 | -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/test_curd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.1.4连接池connpoll/build/test_curd -------------------------------------------------------------------------------- /3.1.4连接池connpoll/build/test_dbpool: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.1.4连接池connpoll/build/test_dbpool -------------------------------------------------------------------------------- /3.1.4连接池connpoll/win32.h: -------------------------------------------------------------------------------- 1 | #ifndef _WIN32_HELPER_INCLUDE 2 | #define _WIN32_HELPER_INCLUDE 3 | #ifdef _MSC_VER 4 | 5 | #ifndef inline 6 | #define inline __inline 7 | #endif 8 | 9 | #ifndef va_copy 10 | #define va_copy(d,s) ((d) = (s)) 11 | #endif 12 | 13 | #ifndef snprintf 14 | #define snprintf c99_snprintf 15 | 16 | __inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) 17 | { 18 | int count = -1; 19 | 20 | if (size != 0) 21 | count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); 22 | if (count == -1) 23 | count = _vscprintf(format, ap); 24 | 25 | return count; 26 | } 27 | 28 | __inline int c99_snprintf(char* str, size_t size, const char* format, ...) 29 | { 30 | int count; 31 | va_list ap; 32 | 33 | va_start(ap, format); 34 | count = c99_vsnprintf(str, size, format, ap); 35 | va_end(ap); 36 | 37 | return count; 38 | } 39 | #endif 40 | 41 | #endif 42 | #endif -------------------------------------------------------------------------------- /3.2.3定时器红黑树最小堆跳表时间轮/mh-timer.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "mh-timer.h" 5 | 6 | void hello_world(timer_entry_t *te) { 7 | printf("hello world time = %u\n", te->time); 8 | } 9 | 10 | int main() { 11 | init_timer(); 12 | 13 | add_timer(3000, hello_world); 14 | 15 | int epfd = epoll_create(1); 16 | struct epoll_event events[512]; 17 | 18 | for (;;) { 19 | int nearest = find_nearest_expire_timer(); 20 | int n = epoll_wait(epfd, events, 512, nearest); 21 | for (int i=0; i < n; i++) { 22 | // 23 | } 24 | expire_timer(); 25 | } 26 | return 0; 27 | } 28 | 29 | // gcc mh-timer.c minheap.c -o mh -I./ -------------------------------------------------------------------------------- /3.2.3定时器红黑树最小堆跳表时间轮/mh-timer.h: -------------------------------------------------------------------------------- 1 | #ifndef MARK_MINHEAP_TIMER_H 2 | #define MARK_MINHEAP_TIMER_H 3 | 4 | #if defined(__APPLE__) 5 | #include 6 | #include 7 | #include 8 | #include 9 | #else 10 | #include 11 | #endif 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "minheap.h" 20 | 21 | static min_heap_t min_heap; 22 | 23 | static uint32_t 24 | current_time() { 25 | uint32_t t; 26 | #if !defined(__APPLE__) || defined(AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER) 27 | struct timespec ti; 28 | clock_gettime(CLOCK_MONOTONIC, &ti); 29 | t = (uint32_t)ti.tv_sec * 1000; 30 | t += ti.tv_nsec / 1000000; 31 | #else 32 | struct timeval tv; 33 | gettimeofday(&tv, NULL); 34 | t = (uint32_t)tv.tv_sec * 1000; 35 | t += tv.tv_usec / 1000; 36 | #endif 37 | return t; 38 | } 39 | 40 | void init_timer() { 41 | min_heap_ctor_(&min_heap); 42 | } 43 | 44 | timer_entry_t * add_timer(uint32_t msec, timer_handler_pt callback) { 45 | timer_entry_t *te = (timer_entry_t *)malloc(sizeof(*te)); 46 | if (!te) { 47 | return NULL; 48 | } 49 | memset(te, 0, sizeof(timer_entry_t)); 50 | 51 | te->handler = callback; 52 | te->time = current_time() + msec; 53 | 54 | if (0 != min_heap_push_(&min_heap, te)) { 55 | free(te); 56 | return NULL; 57 | } 58 | printf("add timer time = %u now = %u\n", te->time, current_time()); 59 | return te; 60 | } 61 | 62 | bool del_timer(timer_entry_t *e) { 63 | return 0 == min_heap_erase_(&min_heap, e); 64 | } 65 | 66 | int find_nearest_expire_timer() { 67 | timer_entry_t *te = min_heap_top_(&min_heap); 68 | if (!te) return -1; 69 | int diff = (int) te->time - (int)current_time(); 70 | return diff > 0 ? diff : 0; 71 | } 72 | 73 | void expire_timer() { 74 | uint32_t cur = current_time(); 75 | for (;;) { 76 | timer_entry_t *te = min_heap_top_(&min_heap); 77 | if (!te) break; 78 | if (te->time > cur) break; 79 | te->handler(te); 80 | min_heap_pop_(&min_heap); 81 | free(te); 82 | } 83 | } 84 | 85 | #endif // MARK_MINHEAP_TIMER_H 86 | -------------------------------------------------------------------------------- /3.2.3定时器红黑树最小堆跳表时间轮/minheap.h: -------------------------------------------------------------------------------- 1 | #ifndef MARK_MINHEAP_H 2 | #define MARK_MINHEAP_H 3 | 4 | #include 5 | #include 6 | 7 | typedef struct timer_entry_s timer_entry_t; 8 | typedef void (*timer_handler_pt)(timer_entry_t *ev); 9 | 10 | struct timer_entry_s { 11 | uint32_t time; 12 | uint32_t min_heap_idx; 13 | timer_handler_pt handler; 14 | void *privdata; 15 | }; 16 | 17 | typedef struct min_heap { 18 | timer_entry_t **p; 19 | uint32_t n, a; // n 为实际元素个数 a 为容量 20 | } min_heap_t; 21 | 22 | void min_heap_ctor_(min_heap_t* s); 23 | void min_heap_dtor_(min_heap_t* s); 24 | void min_heap_elem_init_(timer_entry_t* e); 25 | int min_heap_elt_is_top_(const timer_entry_t *e); 26 | int min_heap_empty_(min_heap_t* s); 27 | unsigned min_heap_size_(min_heap_t* s); 28 | timer_entry_t* min_heap_top_(min_heap_t* s); 29 | int min_heap_reserve_(min_heap_t* s, unsigned n); 30 | int min_heap_push_(min_heap_t* s, timer_entry_t* e); 31 | timer_entry_t* min_heap_pop_(min_heap_t* s); 32 | int min_heap_adjust_(min_heap_t *s, timer_entry_t* e); 33 | int min_heap_erase_(min_heap_t* s, timer_entry_t* e); 34 | void min_heap_shift_up_(min_heap_t* s, unsigned hole_index, timer_entry_t* e); 35 | void min_heap_shift_up_unconditional_(min_heap_t* s, unsigned hole_index, timer_entry_t* e); 36 | void min_heap_shift_down_(min_heap_t* s, unsigned hole_index, timer_entry_t* e); 37 | 38 | #endif // MARK_MINHEAP_H -------------------------------------------------------------------------------- /3.2.3定时器红黑树最小堆跳表时间轮/rbt-timer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "rbt-timer.h" 5 | 6 | void hello_world(timer_entry_t *te) { 7 | printf("hello world time = %u\n", te->rbnode.key); 8 | } 9 | 10 | int main() 11 | { 12 | init_timer(); 13 | 14 | add_timer(3000, hello_world); 15 | 16 | int epfd = epoll_create(1); 17 | struct epoll_event events[512]; 18 | 19 | for (;;) { 20 | int nearest = find_nearest_expire_timer(); 21 | int n = epoll_wait(epfd, events, 512, nearest); 22 | for (int i=0; i < n; i++) { 23 | // 24 | } 25 | expire_timer(); 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /3.2.3定时器红黑树最小堆跳表时间轮/rbtree.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) Igor Sysoev 4 | * Copyright (C) Nginx, Inc. 5 | */ 6 | 7 | #ifndef _NGX_RBTREE_H_INCLUDED_ 8 | #define _NGX_RBTREE_H_INCLUDED_ 9 | 10 | typedef unsigned int ngx_rbtree_key_t; 11 | typedef unsigned int ngx_uint_t; 12 | typedef int ngx_rbtree_key_int_t; 13 | typedef unsigned char u_char; 14 | #ifndef NULL 15 | #define NULL ((void*)0) 16 | #endif 17 | 18 | typedef struct ngx_rbtree_node_s ngx_rbtree_node_t; 19 | 20 | struct ngx_rbtree_node_s { 21 | ngx_rbtree_key_t key; 22 | ngx_rbtree_node_t *left; 23 | ngx_rbtree_node_t *right; 24 | ngx_rbtree_node_t *parent; 25 | u_char color; 26 | u_char data; 27 | }; 28 | 29 | typedef struct ngx_rbtree_s ngx_rbtree_t; 30 | 31 | typedef void (*ngx_rbtree_insert_pt) (ngx_rbtree_node_t *root, 32 | ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); 33 | 34 | struct ngx_rbtree_s { 35 | ngx_rbtree_node_t *root; 36 | ngx_rbtree_node_t *sentinel; 37 | ngx_rbtree_insert_pt insert; 38 | }; 39 | 40 | #define ngx_rbtree_init(tree, s, i) \ 41 | ngx_rbtree_sentinel_init(s); \ 42 | (tree)->root = s; \ 43 | (tree)->sentinel = s; \ 44 | (tree)->insert = i 45 | 46 | void 47 | ngx_rbtree_insert(ngx_rbtree_t *tree, ngx_rbtree_node_t *node); 48 | 49 | void 50 | ngx_rbtree_delete(ngx_rbtree_t *tree, ngx_rbtree_node_t *node); 51 | 52 | void 53 | ngx_rbtree_insert_value(ngx_rbtree_node_t *root, ngx_rbtree_node_t *node, 54 | ngx_rbtree_node_t *sentinel); 55 | 56 | void 57 | ngx_rbtree_insert_timer_value(ngx_rbtree_node_t *root, 58 | ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); 59 | 60 | ngx_rbtree_node_t * 61 | ngx_rbtree_next(ngx_rbtree_t *tree, 62 | ngx_rbtree_node_t *node); 63 | 64 | #define ngx_rbt_red(node) ((node)->color = 1) 65 | #define ngx_rbt_black(node) ((node)->color = 0) 66 | #define ngx_rbt_is_red(node) ((node)->color) 67 | #define ngx_rbt_is_black(node) (!ngx_rbt_is_red(node)) 68 | #define ngx_rbt_copy_color(n1, n2) (n1->color = n2->color) 69 | 70 | /* a sentinel must be black */ 71 | 72 | #define ngx_rbtree_sentinel_init(node) ngx_rbt_black(node) 73 | 74 | static ngx_rbtree_node_t * 75 | ngx_rbtree_min(ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) 76 | { 77 | while (node->left != sentinel) { 78 | node = node->left; 79 | } 80 | 81 | return node; 82 | } 83 | 84 | #endif /* _NGX_RBTREE_H_INCLUDED_ */ 85 | -------------------------------------------------------------------------------- /3.2.3定时器红黑树最小堆跳表时间轮/readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### 编译 4 | 5 | #### 最小堆 6 | 7 | ```shell 8 | # 关联文件 mh-timer.c mh-timer.h minheap.h minheap.c 9 | gcc mh-timer.c minheap.c -o mh -I./ 10 | ``` 11 | 12 | #### 红黑树 13 | 14 | ```shell 15 | # 关联文件 rbt-timer.c rbt-timer.h rbtree.c rbtree.h 16 | gcc rbt-timer.c rbtree.c -o rbt -I./ 17 | ``` 18 | 19 | #### 跳表 20 | 21 | ```shell 22 | # 关联文件 skiplist.h skiplist.c skl-timer.c 23 | gcc skiplist.c skl-timer.c -o skl -I./ 24 | ``` 25 | 26 | #### 单层级时间轮 27 | 28 | ```shell 29 | gcc single_tw.c -o stw 30 | ``` 31 | 32 | #### 多层级时间轮 33 | 34 | ```shell 35 | # 关联文件 timewheel.h timewheel.c tw-timer.c spinlock.h 36 | gcc timewheel.c tw-timer.c -o tw -I./ -lpthread 37 | ``` 38 | 39 | -------------------------------------------------------------------------------- /3.2.3定时器红黑树最小堆跳表时间轮/skiplist.h: -------------------------------------------------------------------------------- 1 | #ifndef _MARK_SKIPLIST_ 2 | #define _MARK_SKIPLIST_ 3 | 4 | /* ZSETs use a specialized version of Skiplists */ 5 | #define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^64 elements */ 6 | #define ZSKIPLIST_P 0.25 /* Skiplist P = 1/2 */ 7 | 8 | typedef struct zskiplistNode zskiplistNode; 9 | typedef void (*handler_pt) (zskiplistNode *node); 10 | struct zskiplistNode { 11 | // sds ele; 12 | // double score; 13 | unsigned long score; // 时间戳 14 | handler_pt handler; 15 | /*struct zskiplistNode *backward; 从后向前遍历时使用*/ 16 | struct zskiplistLevel { 17 | struct zskiplistNode *forward; 18 | /* unsigned long span; 这个存储的level间节点的个数,在定时器中并不需要*/ 19 | } level[]; 20 | }; 21 | 22 | typedef struct zskiplist { 23 | // 添加一个free的函数 24 | struct zskiplistNode *header/*, *tail 并不需要知道最后一个节点*/; 25 | int length; 26 | int level; 27 | } zskiplist; 28 | 29 | zskiplist *zslCreate(void); 30 | void zslFree(zskiplist *zsl); 31 | zskiplistNode *zslInsert(zskiplist *zsl, unsigned long score, handler_pt func); 32 | zskiplistNode* zslMin(zskiplist *zsl); 33 | void zslDeleteHead(zskiplist *zsl); 34 | void zslDelete(zskiplist *zsl, zskiplistNode* zn); 35 | 36 | void zslPrint(zskiplist *zsl); 37 | #endif 38 | -------------------------------------------------------------------------------- /3.2.3定时器红黑树最小堆跳表时间轮/skl-timer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #if defined(__APPLE__) 7 | #include 8 | #include 9 | #include 10 | #include 11 | #else 12 | #include 13 | #endif 14 | #include "skiplist.h" 15 | 16 | static uint32_t 17 | current_time() { 18 | uint32_t t; 19 | #if !defined(__APPLE__) || defined(AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER) 20 | struct timespec ti; 21 | clock_gettime(CLOCK_MONOTONIC, &ti); 22 | t = (uint32_t)ti.tv_sec * 1000; 23 | t += ti.tv_nsec / 1000000; 24 | #else 25 | struct timeval tv; 26 | gettimeofday(&tv, NULL); 27 | t = (uint32_t)tv.tv_sec * 1000; 28 | t += tv.tv_usec / 1000; 29 | #endif 30 | return t; 31 | } 32 | 33 | zskiplist *init_timer() { 34 | return zslCreate(); 35 | } 36 | 37 | zskiplistNode *add_timer(zskiplist *zsl, uint32_t msec, handler_pt func) { 38 | msec += current_time(); 39 | printf("add_timer expire at msec = %u\n", msec); 40 | return zslInsert(zsl, msec, func); 41 | } 42 | 43 | void del_timer(zskiplist *zsl, zskiplistNode *zn) { 44 | zslDelete(zsl, zn); 45 | } 46 | 47 | void expire_timer(zskiplist *zsl) { 48 | zskiplistNode *x; 49 | uint32_t now = current_time(); 50 | for (;;) { 51 | x = zslMin(zsl); 52 | if (!x) break; 53 | if (x->score > now) break; 54 | printf("touch timer expire time=%lu, now = %u\n", x->score, now); 55 | x->handler(x); 56 | zslDeleteHead(zsl); 57 | } 58 | } 59 | 60 | void print_hello(zskiplistNode *zn) { 61 | printf("hello world time = %lu\n", zn->score); 62 | } 63 | 64 | int main() 65 | { 66 | zskiplist *zsl = init_timer(); 67 | add_timer(zsl, 3010, print_hello); 68 | add_timer(zsl, 4004, print_hello); 69 | zskiplistNode *zn = add_timer(zsl, 3005, print_hello); 70 | del_timer(zsl, zn); 71 | add_timer(zsl, 5008, print_hello); 72 | add_timer(zsl, 7003, print_hello); 73 | // zslPrint(zsl); 74 | for (;;) { 75 | expire_timer(zsl); 76 | usleep(10000); 77 | } 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /3.2.3定时器红黑树最小堆跳表时间轮/spinlock.h: -------------------------------------------------------------------------------- 1 | #ifndef SPINLOCK_H 2 | #define SPINLOCK_H 3 | 4 | struct spinlock { 5 | int lock; 6 | }; 7 | 8 | void spinlock_init(struct spinlock *lock) { 9 | lock->lock = 0; 10 | } 11 | 12 | void spinlock_lock(struct spinlock *lock) { 13 | while (__sync_lock_test_and_set(&lock->lock, 1)) {} 14 | } 15 | 16 | int spinlock_trylock(struct spinlock *lock) { 17 | return __sync_lock_test_and_set(&lock->lock, 1) == 0; 18 | } 19 | 20 | void spinlock_unlock(struct spinlock *lock) { 21 | __sync_lock_release(&lock->lock); 22 | } 23 | 24 | void spinlock_destroy(struct spinlock *lock) { 25 | (void) lock; 26 | } 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /3.2.3定时器红黑树最小堆跳表时间轮/timewheel.h: -------------------------------------------------------------------------------- 1 | #ifndef _MARK_TIMEWHEEL_ 2 | #define _MARK_TIMEWHEEL_ 3 | 4 | #include 5 | 6 | #define TIME_NEAR_SHIFT 8 7 | #define TIME_NEAR (1 << TIME_NEAR_SHIFT) 8 | #define TIME_LEVEL_SHIFT 6 9 | #define TIME_LEVEL (1 << TIME_LEVEL_SHIFT) 10 | #define TIME_NEAR_MASK (TIME_NEAR-1) 11 | #define TIME_LEVEL_MASK (TIME_LEVEL-1) 12 | 13 | typedef struct timer_node timer_node_t; 14 | typedef void (*handler_pt) (struct timer_node *node); 15 | 16 | struct timer_node { 17 | struct timer_node *next; 18 | uint32_t expire; 19 | handler_pt callback; 20 | uint8_t cancel; 21 | int id; // 此时携带参数 22 | }; 23 | 24 | timer_node_t* add_timer(int time, handler_pt func, int threadid); 25 | 26 | void expire_timer(void); 27 | 28 | void del_timer(timer_node_t* node); 29 | 30 | void init_timer(void); 31 | 32 | void clear_timer(); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /3.2.3定时器红黑树最小堆跳表时间轮/tw-timer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include "timewheel.h" 8 | 9 | struct context { 10 | int quit; 11 | int thread; 12 | }; 13 | 14 | struct thread_param { 15 | struct context *ctx; 16 | int id; 17 | }; 18 | 19 | static struct context ctx = {0}; 20 | 21 | void do_timer(timer_node_t *node) { 22 | printf("timer expired:%d - thread-id:%d\n", node->expire, node->id); 23 | } 24 | 25 | void* thread_worker(void *p) { 26 | struct thread_param *tp = p; 27 | int id = tp->id; 28 | struct context *ctx = tp->ctx; 29 | while (!ctx->quit) { 30 | int expire = rand() % 200; 31 | add_timer(expire, do_timer, id); 32 | usleep(expire*(10-1)*1000); 33 | } 34 | printf("thread_worker:%d exit!\n", id); 35 | return NULL; 36 | } 37 | 38 | void do_quit(timer_node_t * node) { 39 | ctx.quit = 1; 40 | } 41 | 42 | int main() { 43 | srand(time(NULL)); 44 | ctx.thread = 8; 45 | pthread_t pid[ctx.thread]; 46 | 47 | init_timer(); 48 | add_timer(6000, do_quit, 100); 49 | struct thread_param task_thread_p[ctx.thread]; 50 | int i; 51 | for (i = 0; i < ctx.thread; i++) { 52 | task_thread_p[i].id = i; 53 | task_thread_p[i].ctx = &ctx; 54 | if (pthread_create(&pid[i], NULL, thread_worker, &task_thread_p[i])) { 55 | fprintf(stderr, "create thread failed\n"); 56 | exit(1); 57 | } 58 | } 59 | 60 | while (!ctx.quit) { 61 | expire_timer(); 62 | usleep(2500); 63 | } 64 | clear_timer(); 65 | for (i = 0; i < ctx.thread; i++) { 66 | pthread_join(pid[i], NULL); 67 | } 68 | printf("all thread is closed\n"); 69 | return 0; 70 | } 71 | 72 | // gcc tw-timer.c timewheel.c -o tw -I./ -lpthread -------------------------------------------------------------------------------- /3.2.4无锁队列freequeue/1_test_i++.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-05-31 18:33:36 4 | * @LastEditTime: 2020-05-31 18:34:15 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: \cas\1_test_i++.c 8 | */ 9 | #include 10 | 11 | int i = 0; 12 | 13 | // gcc -S 1_test_i++.c 14 | int main(int argc, char **argv) { 15 | ++i; 16 | return 0; 17 | } -------------------------------------------------------------------------------- /3.2.4无锁队列freequeue/2_test_i++_threads.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-05-31 18:34:32 4 | * @LastEditTime: 2020-05-31 20:33:16 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: \cas\2_test_i++_threads.c 8 | */ 9 | #include 10 | #include 11 | #include 12 | 13 | #define THREAD_NUMBER 2 14 | #define THREAD_INCR_COUNT 100000 15 | static int s_i = 0; 16 | 17 | static int lxx_atomic_add(int *ptr, int increment) { 18 | int old_value = *ptr; 19 | __asm__ volatile("lock; xadd %0, %1 \n\t" 20 | : "=r"(old_value), "=m"(*ptr) 21 | : "0"(increment), "m"(*ptr) 22 | : "cc", "memory"); 23 | return *ptr; 24 | } 25 | 26 | void *thread_increase(void *arg) { 27 | for (int i = 0; i < THREAD_INCR_COUNT; ++i) { 28 | // ++s_i; // ++s_i 会怎么样? 29 | lxx_atomic_add(&s_i, 1); 30 | } 31 | printf("finish\n"); 32 | pthread_exit(NULL); 33 | } 34 | 35 | // 多运行几次 36 | // gcc -o 2_test_i++_threads 2_test_i++_threads.c -lpthread 37 | int main(int argc, char **argv) { 38 | pthread_t threadArr[THREAD_NUMBER]; 39 | for (int i = 0; i < THREAD_NUMBER; ++i) { 40 | pthread_create(&threadArr[i], NULL, thread_increase, NULL); 41 | } 42 | 43 | for (int i = 0; i < THREAD_NUMBER; ++i) { 44 | pthread_join(threadArr[i], NULL); 45 | } 46 | printf("s_i actual:%d, expected:%d\n", s_i, THREAD_NUMBER * THREAD_INCR_COUNT); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /3.2.4无锁队列freequeue/ArrayLockFreeQueue.h: -------------------------------------------------------------------------------- 1 | #ifndef _ARRAYLOCKFREEQUEUE_H___ 2 | #define _ARRAYLOCKFREEQUEUE_H___ 3 | 4 | #include 5 | 6 | #ifdef _WIN64 7 | #define QUEUE_INT int64_t 8 | #else 9 | #define QUEUE_INT unsigned long 10 | #endif 11 | 12 | #define ARRAY_LOCK_FREE_Q_DEFAULT_SIZE 65535 // 2^16 13 | 14 | template 15 | class ArrayLockFreeQueue { 16 | public: 17 | 18 | ArrayLockFreeQueue(); 19 | 20 | virtual ~ArrayLockFreeQueue(); 21 | 22 | QUEUE_INT size(); 23 | 24 | bool enqueue(const ELEM_T &a_data); 25 | 26 | bool dequeue(ELEM_T &a_data); 27 | 28 | bool try_dequeue(ELEM_T &a_data); 29 | 30 | private: 31 | 32 | ELEM_T m_thequeue[Q_SIZE]; 33 | 34 | volatile QUEUE_INT m_count; 35 | volatile QUEUE_INT m_writeIndex; 36 | 37 | volatile QUEUE_INT m_readIndex; 38 | 39 | volatile QUEUE_INT m_maximumReadIndex; 40 | 41 | inline QUEUE_INT countToIndex(QUEUE_INT a_count); 42 | }; 43 | 44 | #include "ArrayLockFreeQueueImp.h" 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /3.2.4无锁队列freequeue/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | project(C++11) 4 | # 设置C++标准为 C++ 11 5 | # set(CMAKE_CXX_STANDARD 11) 6 | # 设置C++标准为 C++ 14 7 | set(CMAKE_CXX_STANDARD 14) 8 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 9 | set(CMAKE_BUILD_TYPE "Debug") 10 | set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g") 11 | add_executable(1_test_i++ 1_test_i++.c) 12 | add_executable(2_test_i++_threads 2_test_i++_threads.c) 13 | add_executable(3_test_mutex_spin_lock 3_test_mutex_spin_lock.cpp) 14 | add_executable(4_test_lock_free_queue 4_test_lock_free_queue.cpp) 15 | target_link_libraries(2_test_i++_threads pthread) 16 | target_link_libraries(3_test_mutex_spin_lock pthread) 17 | target_link_libraries(4_test_lock_free_queue pthread) -------------------------------------------------------------------------------- /3.2.4无锁队列freequeue/atom_opt.h: -------------------------------------------------------------------------------- 1 | #ifndef _ATOM_OPT_H___ 2 | #define _ATOM_OPT_H___ 3 | 4 | #ifdef __GNUC__ 5 | #define CAS(a_ptr, a_oldVal, a_newVal) __sync_bool_compare_and_swap(a_ptr, a_oldVal, a_newVal) 6 | #define AtomicAdd(a_ptr, a_count) __sync_fetch_and_add (a_ptr, a_count) 7 | #define AtomicSub(a_ptr, a_count) __sync_fetch_and_sub (a_ptr, a_count) 8 | 9 | #include // sched_yield() 10 | 11 | #else 12 | 13 | #include 14 | #ifdef _WIN64 15 | #define CAS(a_ptr, a_oldVal, a_newVal) (a_oldVal == InterlockedCompareExchange64(a_ptr, a_newVal, a_oldVal)) 16 | #define sched_yield() SwitchToThread() 17 | #define AtomicAdd(a_ptr, num) InterlockedIncrement64(a_ptr) 18 | #define AtomicSub(a_ptr, num) InterlockedDecrement64(a_ptr) 19 | #else 20 | #define CAS(a_ptr, a_oldVal, a_newVal) (a_oldVal == InterlockedCompareExchange(a_ptr, a_newVal, a_oldVal)) 21 | #define sched_yield() SwitchToThread() 22 | #define AtomicAdd(a_ptr, num) InterlockedIncrement(a_ptr) 23 | #define AtomicSub(a_ptr, num) InterlockedDecrement(a_ptr) 24 | #endif 25 | 26 | #endif 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /3.2.4无锁队列freequeue/readme.md: -------------------------------------------------------------------------------- 1 | # readme 2 | 3 | ```bash 4 | mkdir build 5 | cd build 6 | cmake .. 7 | make 8 | ./4_test_lock_free_queue 9 | ``` -------------------------------------------------------------------------------- /3.2.5死锁检测组件/readme.md: -------------------------------------------------------------------------------- 1 | # gcc 2 | gcc -o deadlock_success deadlock_success.c -lpthread -ldl -------------------------------------------------------------------------------- /3.2.6内存泄漏检测组件/first.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 68725 on 2022/8/13. 3 | // 4 | #define _GNU_SOURCE 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | typedef void *(*malloc_t)(size_t); 13 | 14 | int enable_malloc_hook = 1; 15 | 16 | malloc_t malloc_f; 17 | 18 | typedef void (*free_t)(void *); 19 | 20 | int enable_free_hook = 1; 21 | 22 | free_t free_f; 23 | 24 | static int init_hook() { 25 | malloc_f = dlsym(RTLD_NEXT, "malloc"); 26 | free_f = dlsym(RTLD_NEXT, "free"); 27 | } 28 | 29 | void *ConvertToVMA(void *addr) { 30 | Dl_info info; 31 | struct link_map *link_map; 32 | dladdr1((void *) addr, &info, (void **) &link_map, RTLD_DL_LINKMAP); 33 | return addr - link_map->l_addr; 34 | } 35 | 36 | void *malloc(size_t size) { 37 | if (enable_malloc_hook) { 38 | enable_malloc_hook = 0; 39 | void *p = malloc_f(size); 40 | 41 | void *caller = ConvertToVMA(__builtin_return_address(0)); 42 | printf("[+%p]--->ptr:%p size:%zu\n", caller, p, size); 43 | char command[256]; 44 | Dl_info info; 45 | dladdr(malloc, &info); 46 | snprintf(command, sizeof(command), "addr2line -f -e %s -a %p > ./mem/%p.mem", info.dli_fname, caller, p); 47 | system(command); 48 | 49 | enable_malloc_hook = 1; 50 | return p; 51 | } 52 | else { 53 | return malloc_f(size); 54 | } 55 | } 56 | 57 | void free(void *ptr) { 58 | if (enable_free_hook) { 59 | enable_free_hook = 0; 60 | void *caller = ConvertToVMA(__builtin_return_address(0)); 61 | printf("[-%p]--->ptr:%p\n", caller, ptr); 62 | 63 | char buff[128] = {0}; 64 | sprintf(buff, "./mem/%p.mem", ptr); 65 | if (unlink(buff) < 0) { 66 | printf("double kill:%p\n",ptr); 67 | } 68 | 69 | free_f(ptr); 70 | 71 | enable_free_hook = 1; 72 | } 73 | else { 74 | return free_f(ptr); 75 | } 76 | } 77 | 78 | int main() { 79 | init_hook(); 80 | 81 | void *p1 = malloc(10); 82 | void *p2 = malloc(20); 83 | free(p1); 84 | } 85 | 86 | -------------------------------------------------------------------------------- /3.2.6内存泄漏检测组件/mtrace.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 68725 on 2022/8/16. 3 | // 4 | #include 5 | #include 6 | 7 | int main() { 8 | mtrace(); 9 | 10 | void *p1 = malloc(10); 11 | void *p2 = malloc(20); 12 | void *p3 = malloc(30); 13 | void *p4 = malloc(40); 14 | free(p1); 15 | free(p2); 16 | free(p4); 17 | 18 | muntrace(); 19 | } -------------------------------------------------------------------------------- /3.2.6内存泄漏检测组件/readme.md: -------------------------------------------------------------------------------- 1 | # first 2 | ```bash 3 | root@wxf:/tmp/tmp.d4vz2dOyJP# mkdir mem 4 | root@wxf:/tmp/tmp.d4vz2dOyJP# gcc -o first first.c -ldl -g 5 | root@wxf:/tmp/tmp.d4vz2dOyJP# ./first 6 | root@wxf:/tmp/tmp.d4vz2dOyJP# cd mem/ 7 | root@wxf:/tmp/tmp.d4vz2dOyJP/mem# ls 8 | 0x55f613d27690.mem 9 | root@wxf:/tmp/tmp.d4vz2dOyJP/mem# cat 0x55f613d27690.mem 10 | ``` 11 | 12 | # second 13 | ```bash 14 | root@wxf:/tmp/tmp.d4vz2dOyJP# gcc -o second second.c 15 | root@wxf:/tmp/tmp.d4vz2dOyJP# ./second 16 | double free: 0x559730139500 17 | root@wxf:/tmp/tmp.d4vz2dOyJP# cd mem/ 18 | root@wxf:/tmp/tmp.d4vz2dOyJP/mem# ls 19 | 0x5597301394d0.mem 20 | root@wxf:/tmp/tmp.d4vz2dOyJP/mem# cat 0x5597301394d0.mem 21 | ``` 22 | 23 | # three 24 | ```bash 25 | root@wxf:/tmp/tmp.d4vz2dOyJP# gcc -o three three.c -ldl -g 26 | root@wxf:/tmp/tmp.d4vz2dOyJP# ./three 27 | [+0xc34]--->ptr:0x55b41c3ad260 size:10 28 | [+0xc42]--->ptr:0x55b41c3ad690 size:20 29 | [+0xc50]--->ptr:0x55b41c3ad6b0 size:30 30 | [+0xc5e]--->ptr:0x55b41c3ad6e0 size:40 31 | [-0xc6e]--->ptr:0x55b41c3ad260 32 | [-0xc7a]--->ptr:0x55b41c3ad690 33 | [-0xc86]--->ptr:0x55b41c3ad6e0 34 | root@wxf:/tmp/tmp.d4vz2dOyJP# cd mem/ 35 | root@wxf:/tmp/tmp.d4vz2dOyJP/mem# cat 0x55b41c3ad6b0.mem 36 | 0x0000000000000c50 37 | main 38 | /tmp/tmp.d4vz2dOyJP/three.c:93 39 | ``` 40 | 41 | # mtrace 42 | ```bash 43 | root@wxf:/tmp/tmp.d4vz2dOyJP# export MALLOC_TRACE=./mtrace.log 44 | root@wxf:/tmp/tmp.d4vz2dOyJP# gcc -o mtrace mtrace.c 45 | root@wxf:/tmp/tmp.d4vz2dOyJP# ./mtrace 46 | root@wxf:/tmp/tmp.d4vz2dOyJP# ls 47 | first mem memleak_self.c mtrace.c readme.md second.c three 48 | cmake-build-debug CMakeLists.txt first.c memleak.c mtrace mtrace.log second test.c three.c 49 | root@wxf:/tmp/tmp.d4vz2dOyJP# cat mtrace.log 50 | = Start 51 | @ ./mtrace:[0x558e233f3731] + 0x558e240bf6a0 0xa 52 | @ ./mtrace:[0x558e233f373f] + 0x558e240bf6c0 0x14 53 | @ ./mtrace:[0x558e233f374d] + 0x558e240bf6e0 0x1e 54 | @ ./mtrace:[0x558e233f375b] + 0x558e240bf710 0x28 55 | @ ./mtrace:[0x558e233f376b] - 0x558e240bf6a0 56 | @ ./mtrace:[0x558e233f3777] - 0x558e240bf6c0 57 | @ ./mtrace:[0x558e233f3783] - 0x558e240bf710 58 | = End 59 | ``` -------------------------------------------------------------------------------- /3.2.6内存泄漏检测组件/second.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 68725 on 2022/8/13. 3 | // 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define check_mem_leak 10 | 11 | 12 | void *malloc_def(size_t size, const char *file, const char *func, int line) { 13 | void *p = malloc(size); 14 | 15 | char buff[128] = {0}; 16 | sprintf(buff, "./mem/%p.mem", p); 17 | 18 | FILE *fp = fopen(buff, "w"); 19 | fprintf(fp, "[+%s:%s:%d] --> addr:%p, size:%ld\n", file, func, line, p, size); 20 | fflush(fp); 21 | fclose(fp); 22 | 23 | return p; 24 | } 25 | 26 | void free_def(void *p, const char *file, const char *func, int line) { 27 | char buff[128] = {0}; 28 | sprintf(buff, "./mem/%p.mem", p); 29 | 30 | if (unlink(buff) < 0) { // no exist 31 | printf("double free: %p\n", p); 32 | return; 33 | } 34 | 35 | free(p); 36 | } 37 | 38 | 39 | #ifdef check_mem_leak 40 | #define malloc(size) malloc_def(size,__FILE__,__FUNCTION__ ,__LINE__) 41 | #define free(p) free_def(p,__FILE__,__FUNCTION__ ,__LINE__) 42 | #endif 43 | 44 | int main() { 45 | void *p1 = malloc(10); 46 | void *p2 = malloc(20); 47 | void *p3 = malloc(30); 48 | void *p4 = malloc(40); 49 | free(p1); 50 | free(p2); 51 | free(p4); 52 | free(p4); 53 | } 54 | 55 | -------------------------------------------------------------------------------- /3.2.6内存泄漏检测组件/three.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 68725 on 2022/8/16. 3 | // 4 | #define _GNU_SOURCE 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | typedef void *(*malloc_hook_t)(size_t size, const void *caller); 14 | 15 | malloc_hook_t malloc_f; 16 | 17 | typedef void (*free_hook_t)(void *p, const void *caller); 18 | 19 | free_hook_t free_f; 20 | 21 | int replaced = 0; 22 | 23 | void mem_trace(void); 24 | 25 | void mem_untrace(void); 26 | 27 | const void *ConvertToVMAToSystem_addr2line(const void *addr, const void *ptr) { 28 | Dl_info info; 29 | struct link_map *link_map; 30 | dladdr1((void *) addr, &info, (void **) &link_map, RTLD_DL_LINKMAP); 31 | const void *caller = addr - link_map->l_addr; 32 | 33 | char command[256]; 34 | snprintf(command, sizeof(command), "addr2line -f -e %s -a %p > ./mem/%p.mem", info.dli_fname, caller, ptr); 35 | system(command); 36 | 37 | return caller; 38 | } 39 | 40 | void *malloc_hook_f(size_t size, const void *caller) { 41 | mem_untrace(); 42 | 43 | void *ptr = malloc(size); 44 | 45 | caller = ConvertToVMAToSystem_addr2line(caller, ptr); 46 | printf("[+%p]--->ptr:%p size:%zu\n", caller, ptr, size); 47 | 48 | mem_trace(); 49 | return ptr; 50 | } 51 | 52 | void free_hook_f(void *ptr, const void *caller) { 53 | mem_untrace(); 54 | 55 | caller = ConvertToVMAToSystem_addr2line(caller, ptr); 56 | printf("[-%p]--->ptr:%p\n", caller, ptr); 57 | 58 | char buff[128] = {0}; 59 | sprintf(buff, "./mem/%p.mem", ptr); 60 | if (unlink(buff) < 0) { 61 | printf("double kill:%p\n", ptr); 62 | } 63 | free(ptr); 64 | 65 | mem_trace(); 66 | } 67 | 68 | //replaced=1代表正在trace,__malloc_hook走我们自己写的函数 69 | //replaced=0代表没有trace,__malloc_hook走系统自己的函数 70 | void mem_trace(void) { //mtrace 71 | replaced = 1; 72 | //让malloc_f指向系统的 73 | malloc_f = __malloc_hook; 74 | //free_f 75 | free_f = __free_hook; 76 | //让系统的hook指向我们写的函数 77 | __malloc_hook = malloc_hook_f; 78 | __free_hook = free_hook_f; 79 | } 80 | 81 | void mem_untrace(void) { 82 | //让系统的hook指向系统的malloc和free 83 | __malloc_hook = malloc_f; 84 | __free_hook = free_f; 85 | replaced = 0; 86 | } 87 | 88 | int main() { 89 | mem_trace(); 90 | 91 | void *p1 = malloc(10); 92 | void *p2 = malloc(20); 93 | void *p3 = malloc(30); 94 | void *p4 = malloc(40); 95 | free(p1); 96 | free(p2); 97 | free(p4); 98 | 99 | mem_untrace(); 100 | } -------------------------------------------------------------------------------- /3.3.1libevent-demo/libev/main-ev.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | static void 13 | do_accept(struct ev_loop *reactor, ev_io *w, int events) { 14 | struct sockaddr_in addr; 15 | memset(&addr, 0, sizeof(struct sockaddr_in)); 16 | socklen_t len = sizeof(addr); 17 | int clientfd = accept(w->fd, (struct sockaddr *) &addr, &len); 18 | if (clientfd != -1) 19 | close(clientfd); 20 | 21 | printf("accept fd = %d\n", clientfd); 22 | } 23 | 24 | int socket_listen(uint16_t port) { 25 | int listenfd = socket(AF_INET, SOCK_STREAM, 0); 26 | struct sockaddr_in addr; 27 | memset(&addr, 0, sizeof(struct sockaddr_in)); 28 | 29 | addr.sin_family = AF_INET; 30 | addr.sin_port = htons(port); 31 | addr.sin_addr.s_addr = INADDR_ANY; 32 | 33 | if (bind(listenfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) == -1) 34 | return -1; 35 | 36 | if (listen(listenfd, 5) == -1) 37 | return -1; 38 | 39 | printf("server start listening port:%d\n", port); 40 | return listenfd; 41 | } 42 | 43 | static void 44 | do_timer(struct ev_loop *loop, ev_timer *timer_w, int e) { 45 | time_t now = time(NULL); 46 | printf("do_timer %s", (char *) ctime(&now)); 47 | // ev_timer_stop(loop, timer_w); 48 | } 49 | 50 | int main() { 51 | struct ev_loop *loop = ev_loop_new(0); 52 | 53 | struct ev_timer t1; 54 | ev_timer_init(&t1, do_timer, 1, 1); 55 | ev_timer_start(loop, &t1); 56 | 57 | int listenfd = socket_listen(8989); 58 | if (listenfd == -1) return -2; 59 | struct ev_io i1; 60 | ev_io_init(&i1, do_accept, listenfd, EV_READ); 61 | ev_io_start(loop, &i1); 62 | ev_run(loop, 0); 63 | 64 | ev_loop_destroy(loop); 65 | return 0; 66 | } 67 | 68 | /* 69 | gcc main-ev.c -o main-ev -I../libev/ -L../libev/.libs/ -lev 70 | */ 71 | -------------------------------------------------------------------------------- /3.3.1libevent-demo/libev/main-event.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include "event.h" 11 | 12 | static struct event evtimer; 13 | 14 | static void 15 | do_accept(int fd, short events, void *arg) { 16 | struct event_base *ev = (struct event_base *) arg; 17 | struct sockaddr_in addr; 18 | memset(&addr, 0, sizeof(struct sockaddr_in)); 19 | socklen_t len = sizeof(addr); 20 | int clientfd = accept(fd, (struct sockaddr *) &addr, &len); 21 | if (clientfd != -1) 22 | close(clientfd); 23 | 24 | printf("accept fd = %d\n", clientfd); 25 | } 26 | 27 | static void 28 | do_timer(int fd, short events, void *arg) { 29 | time_t now = time(NULL); 30 | printf("do_timer %s", (char *) ctime(&now)); 31 | struct timeval tv; 32 | tv.tv_sec = 1; 33 | tv.tv_usec = 0; 34 | event_add(&evtimer, &tv); 35 | } 36 | 37 | int socket_listen(uint16_t port) { 38 | int listenfd = socket(AF_INET, SOCK_STREAM, 0); 39 | struct sockaddr_in addr; 40 | memset(&addr, 0, sizeof(struct sockaddr_in)); 41 | 42 | addr.sin_family = AF_INET; 43 | addr.sin_port = htons(port); 44 | addr.sin_addr.s_addr = INADDR_ANY; 45 | 46 | if (bind(listenfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) == -1) 47 | return -1; 48 | 49 | if (listen(listenfd, 5) == -1) 50 | return -1; 51 | 52 | printf("server start listening port:%d\n", port); 53 | 54 | return listenfd; 55 | } 56 | 57 | int main() { 58 | 59 | struct event_base *ev = event_init(); 60 | 61 | struct event evlisten; 62 | 63 | struct timeval tv; 64 | tv.tv_sec = 1; 65 | tv.tv_usec = 0; 66 | 67 | int listenfd = socket_listen(8989); 68 | if (listenfd == -1) return -2; 69 | 70 | event_set(&evlisten, listenfd, EV_READ | EV_PERSIST, do_accept, ev); 71 | event_base_set(ev, &evlisten); 72 | event_add(&evlisten, NULL); 73 | 74 | event_set(&evtimer, -1, 0, do_timer, ev); 75 | event_base_set(ev, &evtimer); 76 | event_add(&evtimer, &tv); 77 | 78 | event_base_dispatch(ev); 79 | 80 | event_base_free(ev); 81 | return 0; 82 | } 83 | 84 | /* 85 | // gcc main-event.c -o main-event -I../libev/ -L../libev/.libs/ -lev 86 | */ 87 | 88 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "algorithm": "cpp", 4 | "cmath": "cpp", 5 | "cstddef": "cpp", 6 | "cstdint": "cpp", 7 | "cstdio": "cpp", 8 | "cstdlib": "cpp", 9 | "cstring": "cpp", 10 | "cwchar": "cpp", 11 | "exception": "cpp", 12 | "hash_map": "cpp", 13 | "initializer_list": "cpp", 14 | "ios": "cpp", 15 | "iosfwd": "cpp", 16 | "iostream": "cpp", 17 | "istream": "cpp", 18 | "limits": "cpp", 19 | "list": "cpp", 20 | "map": "cpp", 21 | "memory": "cpp", 22 | "new": "cpp", 23 | "ostream": "cpp", 24 | "set": "cpp", 25 | "sstream": "cpp", 26 | "stdexcept": "cpp", 27 | "streambuf": "cpp", 28 | "string": "cpp", 29 | "system_error": "cpp", 30 | "tuple": "cpp", 31 | "type_traits": "cpp", 32 | "typeinfo": "cpp", 33 | "utility": "cpp", 34 | "vector": "cpp", 35 | "xfacet": "cpp", 36 | "xhash": "cpp", 37 | "xiosbase": "cpp", 38 | "xlocale": "cpp", 39 | "xlocinfo": "cpp", 40 | "xlocnum": "cpp", 41 | "xmemory": "cpp", 42 | "xmemory0": "cpp", 43 | "xstddef": "cpp", 44 | "xstring": "cpp", 45 | "xtr1common": "cpp", 46 | "xtree": "cpp", 47 | "xutility": "cpp" 48 | } 49 | } -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | project (im) 4 | 5 | ADD_DEFINITIONS( -g -W -Wall -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DAC_HAS_INFO 6 | -DAC_HAS_WARNING -DAC_HAS_ERROR -DAC_HAS_CRITICAL -DTIXML_USE_STL 7 | -DAC_HAS_DEBUG -DLINUX_DAEMON -std=c++11) 8 | 9 | set(im_srcs 10 | msg.pb.cc 11 | IM.BaseDefine.pb.cc 12 | IM.Login.pb.cc 13 | IM.Message.pb.cc 14 | UtilPdu.cc 15 | ImPduBase.cc 16 | util.cc 17 | Lock.cc 18 | ) 19 | 20 | set(server_srcs 21 | server.cc 22 | ) 23 | 24 | set(client_srcs 25 | client.cc 26 | ) 27 | 28 | add_executable(server_im ${im_srcs} ${server_srcs}) 29 | add_executable(client_im ${im_srcs} ${client_srcs}) 30 | TARGET_LINK_LIBRARIES(server_im protobuf pthread) 31 | TARGET_LINK_LIBRARIES(client_im protobuf pthread) 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/IM.Login.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; // proto2和proto3 2 | package IM.Login; //IM::Login -> package IM.Login 3 | import "IM.BaseDefine.proto"; // 引用文件 4 | 5 | option optimize_for = LITE_RUNTIME; 6 | 7 | message IMLoginReq{ 8 | //cmd id: 0x0103 9 | string user_name = 1; 10 | string password = 2; 11 | IM.BaseDefine.UserStatType online_status = 3; 12 | IM.BaseDefine.ClientType client_type = 4; 13 | string client_version = 5; 14 | } 15 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/IM.Message.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package IM.Message; 3 | import "IM.BaseDefine.proto"; 4 | 5 | option optimize_for = LITE_RUNTIME; 6 | 7 | //service id 0x0003 8 | message IMMsgData{ 9 | //cmd id: 0x0301 10 | uint32 from_user_id = 1; //消息发送方 11 | uint32 to_session_id = 2; //消息接受方 12 | uint32 msg_id = 3; //消息ID 13 | uint32 create_time = 4; //创建时间 14 | IM.BaseDefine.MsgType msg_type = 5; 15 | bytes msg_data = 6; 16 | bytes attach_data = 20; 17 | } 18 | 19 | message IMMsgDataAck{ 20 | //cmd id: 0x0302 21 | uint32 user_id = 1; //发送此信令的用户id 22 | uint32 session_id = 2; 23 | uint32 msg_id = 3; 24 | IM.BaseDefine.SessionType session_type = 4; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/ImPduBase.h: -------------------------------------------------------------------------------- 1 | #ifndef IMPDUBASE_H_ 2 | #define IMPDUBASE_H_ 3 | 4 | #include 5 | 6 | #include "ostype.h" 7 | #include "UtilPdu.h" 8 | 9 | #define IM_PDU_HEADER_LEN 16 10 | #define IM_PDU_VERSION 1 11 | 12 | 13 | ////////////////////////////// 14 | typedef struct { 15 | uint32_t length; // the whole pdu length 16 | uint16_t version; // pdu version number 17 | uint16_t flag; // not used 18 | uint16_t service_id; // 19 | uint16_t command_id; // 20 | uint16_t seq_num; // 包序号 21 | uint16_t reversed; // 保留 22 | } PduHeader_t; 23 | 24 | 25 | class CImPdu 26 | { 27 | public: 28 | CImPdu(); 29 | virtual ~CImPdu() {} 30 | 31 | uchar_t* GetBuffer(); 32 | uint32_t GetLength(); 33 | uchar_t* GetBodyData(); 34 | uint32_t GetBodyLength(); 35 | 36 | 37 | uint16_t GetVersion() { return m_pdu_header.version; } 38 | uint16_t GetFlag() { return m_pdu_header.flag; } 39 | uint16_t GetServiceId() { return m_pdu_header.service_id; } 40 | uint16_t GetCommandId() { return m_pdu_header.command_id; } 41 | uint16_t GetSeqNum() { return m_pdu_header.seq_num; } 42 | uint32_t GetReversed() { return m_pdu_header.reversed; } 43 | 44 | void SetVersion(uint16_t version); 45 | void SetFlag(uint16_t flag); 46 | void SetServiceId(uint16_t service_id); 47 | void SetCommandId(uint16_t command_id); 48 | void SetError(uint16_t error); 49 | void SetSeqNum(uint16_t seq_num); 50 | void SetReversed(uint32_t reversed); 51 | void WriteHeader(); 52 | 53 | static bool IsPduAvailable(uchar_t* buf, uint32_t len, uint32_t& pdu_len); 54 | static CImPdu* ReadPdu(uchar_t* buf, uint32_t len); 55 | void Write(uchar_t* buf, uint32_t len) { m_buf.Write((void*)buf, len); } 56 | int ReadPduHeader(uchar_t* buf, uint32_t len); 57 | void SetPBMsg(const google::protobuf::MessageLite* msg); 58 | 59 | protected: 60 | CSimpleBuffer m_buf; // 缓存buffer, m_pdu_header + PB序列化后的数据 61 | PduHeader_t m_pdu_header; 62 | }; 63 | 64 | 65 | #endif 66 | 67 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/Lock.cc: -------------------------------------------------------------------------------- 1 | /*================================================================ 2 | * Copyright (C) 2014 All rights reserved. 3 | * 4 | * 文件名称:Lock.cpp 5 | * 创 建 者:Zhang Yuanhao 6 | * 邮 箱:bluefoxah@gmail.com 7 | * 创建日期:2014年09月10日 8 | * 描 述: 9 | * 10 | #include "Lock.h" 11 | ================================================================*/ 12 | 13 | #include "Lock.h" 14 | 15 | CLock::CLock() 16 | { 17 | #ifdef _WIN32 18 | InitializeCriticalSection(&m_critical_section); 19 | #else 20 | pthread_mutex_init(&m_lock,NULL); 21 | #endif 22 | } 23 | 24 | CLock::~CLock() 25 | { 26 | #ifdef _WIN32 27 | DeleteCriticalSection(&m_critical_section); 28 | #else 29 | pthread_mutex_destroy(&m_lock); 30 | #endif 31 | } 32 | 33 | void CLock::lock() 34 | { 35 | #ifdef _WIN32 36 | EnterCriticalSection(&m_critical_section); 37 | #else 38 | pthread_mutex_lock(&m_lock); 39 | #endif 40 | } 41 | 42 | void CLock::unlock() 43 | { 44 | #ifdef _WIN32 45 | LeaveCriticalSection(&m_critical_section); 46 | #else 47 | pthread_mutex_unlock(&m_lock); 48 | #endif 49 | } 50 | 51 | #ifndef _WIN32 52 | bool CLock::try_lock() 53 | { 54 | return pthread_mutex_trylock(&m_lock) == 0; 55 | } 56 | #endif 57 | 58 | #ifndef _WIN32 59 | CRWLock::CRWLock() 60 | { 61 | pthread_rwlock_init(&m_lock, NULL); 62 | } 63 | 64 | CRWLock::~CRWLock() 65 | { 66 | pthread_rwlock_destroy(&m_lock); 67 | } 68 | 69 | void CRWLock::rlock() 70 | { 71 | pthread_rwlock_rdlock(&m_lock); 72 | } 73 | 74 | void CRWLock::wlock() 75 | { 76 | pthread_rwlock_wrlock(&m_lock); 77 | } 78 | 79 | void CRWLock::unlock() 80 | { 81 | pthread_rwlock_unlock(&m_lock); 82 | } 83 | 84 | bool CRWLock::try_rlock() 85 | { 86 | return pthread_rwlock_tryrdlock(&m_lock) == 0; 87 | } 88 | 89 | bool CRWLock::try_wlock() 90 | { 91 | return pthread_rwlock_trywrlock(&m_lock) == 0; 92 | } 93 | 94 | 95 | CAutoRWLock::CAutoRWLock(CRWLock* pLock, bool bRLock) 96 | { 97 | m_pLock = pLock; 98 | if(NULL != m_pLock) 99 | { 100 | if (bRLock) { 101 | m_pLock->rlock(); 102 | } 103 | else 104 | { 105 | m_pLock->wlock(); 106 | } 107 | } 108 | } 109 | 110 | CAutoRWLock::~CAutoRWLock() 111 | { 112 | if(NULL != m_pLock) 113 | { 114 | m_pLock->unlock(); 115 | } 116 | } 117 | #endif 118 | 119 | CAutoLock::CAutoLock(CLock* pLock) 120 | { 121 | m_pLock = pLock; 122 | if(NULL != m_pLock) 123 | m_pLock->lock(); 124 | } 125 | 126 | CAutoLock::~CAutoLock() 127 | { 128 | if(NULL != m_pLock) 129 | m_pLock->unlock(); 130 | } 131 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/Lock.h: -------------------------------------------------------------------------------- 1 | /*================================================================ 2 | * Copyright (C) 2014 All rights reserved. 3 | * 4 | * 文件名称:Lock.h 5 | * 创 建 者:Zhang Yuanhao 6 | * 邮 箱:bluefoxah@gmail.com 7 | * 创建日期:2014年09月10日 8 | * 描 述: 9 | * 10 | #pragma once 11 | ================================================================*/ 12 | 13 | #ifndef __LOCK_H__ 14 | #define __LOCK_H__ 15 | 16 | #include "ostype.h" 17 | 18 | class CLock 19 | { 20 | public: 21 | CLock(); 22 | virtual ~CLock(); 23 | void lock(); 24 | void unlock(); 25 | pthread_mutex_t& getMutex() { return m_lock; } 26 | #ifndef _WIN32 27 | virtual bool try_lock(); 28 | #endif 29 | private: 30 | #ifdef _WIN32 31 | CRITICAL_SECTION m_critical_section; 32 | #else 33 | pthread_mutex_t m_lock; 34 | #endif 35 | }; 36 | 37 | #ifndef _WIN32 38 | class CRWLock 39 | { 40 | public: 41 | CRWLock(); 42 | virtual ~CRWLock(); 43 | void rlock(); 44 | void wlock(); 45 | void unlock(); 46 | bool try_rlock(); 47 | bool try_wlock(); 48 | private: 49 | pthread_rwlock_t m_lock; 50 | }; 51 | 52 | class CAutoRWLock 53 | { 54 | public: 55 | CAutoRWLock(CRWLock* pLock, bool bRLock = true); 56 | virtual ~CAutoRWLock(); 57 | private: 58 | CRWLock* m_pLock; 59 | }; 60 | 61 | #endif 62 | 63 | class CAutoLock 64 | { 65 | public: 66 | CAutoLock(CLock* pLock); 67 | virtual ~CAutoLock(); 68 | private: 69 | CLock* m_pLock; 70 | }; 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/bad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.3.2protobuf/2-protobuf/1-im/bad -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/bad.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-05-14 18:01:26 4 | * @LastEditTime: 2020-05-14 20:24:11 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: \im\bad.cpp 8 | */ 9 | #include 10 | #include 11 | 12 | struct Person1 13 | { 14 | char name[15]; // 姓名 16 + 4 + 24 15 | int age; // 年龄 16 | char phone[21]; // 电话 17 | }; 18 | 19 | struct Person2 20 | { 21 | char name[15]; // 姓名 15 + 4 + 21 = 40 22 | int age; // 年龄 23 | char phone[21]; 24 | /* data */ 25 | }__attribute__((packed));; 26 | 27 | /* 28 | sizeof(Persion1) = 44 29 | sizeof(Persion2) = 40 30 | */ 31 | int main() 32 | { 33 | printf("sizeof(Person1) = %lu\n", sizeof(struct Person1)); 34 | printf("sizeof(Person2) = %lu\n", sizeof(struct Person2)); 35 | return 0; 36 | } -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/client_im: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.3.2protobuf/2-protobuf/1-im/client_im -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/create.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | SRC_DIR=./ 3 | DST_DIR=./ 4 | 5 | #C++ 6 | mkdir -p $DST_DIR/cpp 7 | protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/*.proto 8 | 9 | 10 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/helloworld.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option java_multiple_files = true; 4 | option java_package = "io.grpc.examples.helloworld"; 5 | option java_outer_classname = "HelloWorldProto"; 6 | option objc_class_prefix = "HLW"; 7 | 8 | package helloworld; 9 | 10 | // The greeting service definition. 11 | service Greeter { 12 | // Sends a greeting 13 | rpc SayHello (HelloRequest) returns (HelloReply) {} 14 | } 15 | 16 | // The request message containing the user's name. 17 | message HelloRequest { 18 | string name = 1; 19 | } 20 | 21 | // The response message containing the greetings 22 | message HelloReply { 23 | string message = 1; 24 | } -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/msg.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package Im; 3 | message helloworld 4 | { 5 | int32 id = 1; 6 | string str = 2; 7 | int32 opt = 3; 8 | } 9 | message worldhello 10 | { 11 | int32 id = 1; 12 | string str = 2; 13 | int32 otp = 3; 14 | } -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/pack_test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.3.2protobuf/2-protobuf/1-im/pack_test -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/pack_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-02-14 19:41:58 4 | * @LastEditTime : 2020-02-14 19:48:40 5 | * @LastEditors : Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: \im\pack_test.cpp 8 | */ 9 | #include 10 | #include 11 | 12 | #pragma pack(4) 13 | class CBase4 14 | { 15 | private: 16 | char a; 17 | short b; 18 | int c; 19 | public: 20 | void printSize() 21 | { 22 | std::cout << "sizeof(class CBase4) = " << sizeof(class CBase4) << std::endl; 23 | } 24 | }; 25 | 26 | #pragma pack(1) 27 | class CBase1 28 | { 29 | private: 30 | char a; 31 | short b; 32 | int c; 33 | public: 34 | void printSize() 35 | { 36 | std::cout << "sizeof(class CBase1) = " << sizeof(class CBase1) << std::endl; 37 | } 38 | }; 39 | 40 | int main(void) 41 | { 42 | CBase4 base4; 43 | base4.printSize(); 44 | CBase1 base1; 45 | base1.printSize(); 46 | return 0; 47 | } -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/rpc_server.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-01-08 19:47:40 4 | * @LastEditTime: 2020-01-08 19:47:54 5 | * @LastEditors: your name 6 | * @Description: In User Settings Edit 7 | * @FilePath: \im\rpc_server.cpp 8 | */ 9 | /* 10 | * 11 | * Copyright 2015 gRPC authors. 12 | * 13 | * Licensed under the Apache License, Version 2.0 (the "License"); 14 | * you may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at 16 | * 17 | * http://www.apache.org/licenses/LICENSE-2.0 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | #ifdef BAZEL_BUILD 34 | #include "examples/protos/helloworld.grpc.pb.h" 35 | #else 36 | #include "helloworld.grpc.pb.h" 37 | #endif 38 | 39 | using grpc::Server; 40 | using grpc::ServerBuilder; 41 | using grpc::ServerContext; 42 | using grpc::Status; 43 | using helloworld::HelloRequest; 44 | using helloworld::HelloReply; 45 | using helloworld::Greeter; 46 | 47 | // Logic and data behind the server's behavior. 48 | class GreeterServiceImpl final : public Greeter::Service { 49 | Status SayHello(ServerContext* context, const HelloRequest* request, 50 | HelloReply* reply) override { 51 | std::string prefix("Hello "); 52 | reply->set_message(prefix + request->name()); 53 | return Status::OK; 54 | } 55 | }; 56 | 57 | void RunServer() { 58 | std::string server_address("0.0.0.0:50051"); 59 | GreeterServiceImpl service; 60 | 61 | ServerBuilder builder; 62 | // Listen on the given address without any authentication mechanism. 63 | builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); 64 | // Register "service" as the instance through which we'll communicate with 65 | // clients. In this case it corresponds to an *synchronous* service. 66 | builder.RegisterService(&service); 67 | // Finally assemble the server. 68 | std::unique_ptr server(builder.BuildAndStart()); 69 | std::cout << "Server listening on " << server_address << std::endl; 70 | 71 | // Wait for the server to shutdown. Note that some other thread must be 72 | // responsible for shutting down the server for this call to ever return. 73 | server->Wait(); 74 | } 75 | 76 | int main(int argc, char** argv) { 77 | RunServer(); 78 | 79 | return 0; 80 | } -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/server_im: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.3.2protobuf/2-protobuf/1-im/server_im -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/1-im/util.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTIL_H__ 2 | #define __UTIL_H__ 3 | 4 | #define _CRT_SECURE_NO_DEPRECATE // remove warning C4996, 5 | 6 | #include "ostype.h" 7 | #include "UtilPdu.h" 8 | #include "Lock.h" 9 | #include 10 | #include 11 | #include 12 | #ifndef _WIN32 13 | #include 14 | #endif 15 | 16 | #include 17 | #include 18 | 19 | 20 | #ifdef _WIN32 21 | #define snprintf sprintf_s 22 | #else 23 | #include 24 | #include 25 | #include 26 | #include 27 | #endif 28 | 29 | #define NOTUSED_ARG(v) ((void)v) // used this to remove warning C4100, unreferenced parameter 30 | 31 | /// yunfan modify end 32 | class CRefObject 33 | { 34 | public: 35 | CRefObject(); 36 | virtual ~CRefObject(); 37 | 38 | void SetLock(CLock* lock) { m_lock = lock; } 39 | void AddRef(); 40 | void ReleaseRef(); 41 | private: 42 | int m_refCount; 43 | CLock* m_lock; 44 | }; 45 | 46 | #define LOG_MODULE_IM "IM" 47 | 48 | 49 | 50 | // Add By ZhangYuanhao 2015-01-14 For log show the file name not the full path + filename 51 | #define __FILENAME__ (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1):__FILE__) 52 | #if defined(_WIN32) || defined(_WIN64) 53 | #define log(fmt, ...) 54 | #else 55 | #define log(fmt, args...) 56 | #define log_debug(fmt, args...) 57 | #define log_warn(fmt, args...) 58 | #define log_error(fmt, args...) 59 | #define log_fatal(fmt, args...) 60 | #endif 61 | //#define log(fmt, ...) g_imlog.Info("<%s>\t<%d>\t<%s>,"+fmt, __FILENAME__, __LINE__, __FUNCTION__, ##__VA_ARGS__) 62 | 63 | uint64_t get_tick_count(); 64 | void util_sleep(uint32_t millisecond); 65 | 66 | 67 | class CStrExplode 68 | { 69 | public: 70 | CStrExplode(char* str, char seperator); 71 | virtual ~CStrExplode(); 72 | 73 | uint32_t GetItemCnt() { return m_item_cnt; } 74 | char* GetItem(uint32_t idx) { return m_item_list[idx]; } 75 | private: 76 | uint32_t m_item_cnt; 77 | char** m_item_list; 78 | }; 79 | 80 | char* replaceStr(char* pSrc, char oldChar, char newChar); 81 | string int2string(uint32_t user_id); 82 | uint32_t string2int(const string& value); 83 | void replace_mark(string& str, string& new_value, uint32_t& begin_pos); 84 | void replace_mark(string& str, uint32_t new_value, uint32_t& begin_pos); 85 | 86 | void writePid(); 87 | inline unsigned char toHex(const unsigned char &x); 88 | inline unsigned char fromHex(const unsigned char &x); 89 | string URLEncode(const string &sIn); 90 | string URLDecode(const string &sIn); 91 | 92 | 93 | int64_t get_file_size(const char *path); 94 | const char* memfind(const char *src_str,size_t src_len, const char *sub_str, size_t sub_len, bool flag = true); 95 | 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/2-im_new/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | project (im) 4 | 5 | ADD_DEFINITIONS( -g -W -Wall -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DAC_HAS_INFO 6 | -DAC_HAS_WARNING -DAC_HAS_ERROR -DAC_HAS_CRITICAL -DTIXML_USE_STL 7 | -DAC_HAS_DEBUG -DLINUX_DAEMON -std=c++11) 8 | 9 | set(im_srcs 10 | msg.pb.cc 11 | IM.BaseDefine.pb.cc 12 | IM.Login.pb.cc 13 | IM.Message.pb.cc 14 | UtilPdu.cc 15 | ImPduBase.cc 16 | util.cc 17 | Lock.cc 18 | ) 19 | 20 | set(server_srcs 21 | server.cc 22 | ) 23 | 24 | set(client_srcs 25 | client.cc 26 | ) 27 | 28 | add_executable(server_im ${im_srcs} ${server_srcs}) 29 | add_executable(client_im ${im_srcs} ${client_srcs}) 30 | TARGET_LINK_LIBRARIES(server_im protobuf pthread) 31 | TARGET_LINK_LIBRARIES(client_im protobuf pthread) 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/2-im_new/IM.Login.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package IM.Login; 3 | import "IM.BaseDefine.proto"; 4 | 5 | option optimize_for = LITE_RUNTIME; 6 | 7 | message IMLoginReq{ 8 | //cmd id: 0x0103 9 | string user_name = 1; 10 | string password = 2; 11 | IM.BaseDefine.UserStatType online_status = 3; 12 | IM.BaseDefine.ClientType client_type = 4; 13 | string client_version = 5; 14 | string client = 6; 15 | string tails = 7; 16 | } 17 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/2-im_new/IM.Message.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package IM.Message; 3 | import "IM.BaseDefine.proto"; 4 | 5 | option optimize_for = LITE_RUNTIME; 6 | 7 | //service id 0x0003 8 | message IMMsgData{ 9 | //cmd id: 0x0301 10 | uint32 from_user_id = 1; //消息发送方 11 | uint32 to_session_id = 2; //消息接受方 12 | uint32 msg_id = 3; //消息ID 13 | uint32 create_time = 4; //创建时间 14 | IM.BaseDefine.MsgType msg_type = 5; 15 | bytes msg_data = 6; 16 | bytes attach_data = 20; 17 | } 18 | 19 | message IMMsgDataAck{ 20 | //cmd id: 0x0302 21 | uint32 user_id = 1; //发送此信令的用户id 22 | uint32 session_id = 2; 23 | uint32 msg_id = 3; 24 | IM.BaseDefine.SessionType session_type = 4; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/2-im_new/ImPduBase.h: -------------------------------------------------------------------------------- 1 | #ifndef IMPDUBASE_H_ 2 | #define IMPDUBASE_H_ 3 | 4 | #include 5 | 6 | #include "ostype.h" 7 | #include "UtilPdu.h" 8 | 9 | #define IM_PDU_HEADER_LEN 16 10 | #define IM_PDU_VERSION 1 11 | 12 | 13 | ////////////////////////////// 14 | typedef struct { 15 | uint32_t length; // the whole pdu length 16 | uint16_t version; // pdu version number 17 | uint16_t flag; // not used 18 | uint16_t service_id; // 19 | uint16_t command_id; // 20 | uint16_t seq_num; // 包序号 21 | uint16_t reversed; // 保留 22 | } PduHeader_t; 23 | 24 | 25 | class CImPdu 26 | { 27 | public: 28 | CImPdu(); 29 | virtual ~CImPdu() {} 30 | 31 | uchar_t* GetBuffer(); 32 | uint32_t GetLength(); 33 | uchar_t* GetBodyData(); 34 | uint32_t GetBodyLength(); 35 | 36 | 37 | uint16_t GetVersion() { return m_pdu_header.version; } 38 | uint16_t GetFlag() { return m_pdu_header.flag; } 39 | uint16_t GetServiceId() { return m_pdu_header.service_id; } 40 | uint16_t GetCommandId() { return m_pdu_header.command_id; } 41 | uint16_t GetSeqNum() { return m_pdu_header.seq_num; } 42 | uint32_t GetReversed() { return m_pdu_header.reversed; } 43 | 44 | void SetVersion(uint16_t version); 45 | void SetFlag(uint16_t flag); 46 | void SetServiceId(uint16_t service_id); 47 | void SetCommandId(uint16_t command_id); 48 | void SetError(uint16_t error); 49 | void SetSeqNum(uint16_t seq_num); 50 | void SetReversed(uint32_t reversed); 51 | void WriteHeader(); 52 | 53 | static bool IsPduAvailable(uchar_t* buf, uint32_t len, uint32_t& pdu_len); 54 | static CImPdu* ReadPdu(uchar_t* buf, uint32_t len); 55 | void Write(uchar_t* buf, uint32_t len) { m_buf.Write((void*)buf, len); } 56 | int ReadPduHeader(uchar_t* buf, uint32_t len); 57 | void SetPBMsg(const google::protobuf::MessageLite* msg); 58 | 59 | protected: 60 | CSimpleBuffer m_buf; // 缓存buffer, m_pdu_header + PB序列化后的数据 61 | PduHeader_t m_pdu_header; 62 | }; 63 | 64 | 65 | #endif 66 | 67 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/2-im_new/Lock.cc: -------------------------------------------------------------------------------- 1 | /*================================================================ 2 | * Copyright (C) 2014 All rights reserved. 3 | * 4 | * 文件名称:Lock.cpp 5 | * 创 建 者:Zhang Yuanhao 6 | * 邮 箱:bluefoxah@gmail.com 7 | * 创建日期:2014年09月10日 8 | * 描 述: 9 | * 10 | #include "Lock.h" 11 | ================================================================*/ 12 | 13 | #include "Lock.h" 14 | 15 | CLock::CLock() 16 | { 17 | #ifdef _WIN32 18 | InitializeCriticalSection(&m_critical_section); 19 | #else 20 | pthread_mutex_init(&m_lock,NULL); 21 | #endif 22 | } 23 | 24 | CLock::~CLock() 25 | { 26 | #ifdef _WIN32 27 | DeleteCriticalSection(&m_critical_section); 28 | #else 29 | pthread_mutex_destroy(&m_lock); 30 | #endif 31 | } 32 | 33 | void CLock::lock() 34 | { 35 | #ifdef _WIN32 36 | EnterCriticalSection(&m_critical_section); 37 | #else 38 | pthread_mutex_lock(&m_lock); 39 | #endif 40 | } 41 | 42 | void CLock::unlock() 43 | { 44 | #ifdef _WIN32 45 | LeaveCriticalSection(&m_critical_section); 46 | #else 47 | pthread_mutex_unlock(&m_lock); 48 | #endif 49 | } 50 | 51 | #ifndef _WIN32 52 | bool CLock::try_lock() 53 | { 54 | return pthread_mutex_trylock(&m_lock) == 0; 55 | } 56 | #endif 57 | 58 | #ifndef _WIN32 59 | CRWLock::CRWLock() 60 | { 61 | pthread_rwlock_init(&m_lock, NULL); 62 | } 63 | 64 | CRWLock::~CRWLock() 65 | { 66 | pthread_rwlock_destroy(&m_lock); 67 | } 68 | 69 | void CRWLock::rlock() 70 | { 71 | pthread_rwlock_rdlock(&m_lock); 72 | } 73 | 74 | void CRWLock::wlock() 75 | { 76 | pthread_rwlock_wrlock(&m_lock); 77 | } 78 | 79 | void CRWLock::unlock() 80 | { 81 | pthread_rwlock_unlock(&m_lock); 82 | } 83 | 84 | bool CRWLock::try_rlock() 85 | { 86 | return pthread_rwlock_tryrdlock(&m_lock) == 0; 87 | } 88 | 89 | bool CRWLock::try_wlock() 90 | { 91 | return pthread_rwlock_trywrlock(&m_lock) == 0; 92 | } 93 | 94 | 95 | CAutoRWLock::CAutoRWLock(CRWLock* pLock, bool bRLock) 96 | { 97 | m_pLock = pLock; 98 | if(NULL != m_pLock) 99 | { 100 | if (bRLock) { 101 | m_pLock->rlock(); 102 | } 103 | else 104 | { 105 | m_pLock->wlock(); 106 | } 107 | } 108 | } 109 | 110 | CAutoRWLock::~CAutoRWLock() 111 | { 112 | if(NULL != m_pLock) 113 | { 114 | m_pLock->unlock(); 115 | } 116 | } 117 | #endif 118 | 119 | CAutoLock::CAutoLock(CLock* pLock) 120 | { 121 | m_pLock = pLock; 122 | if(NULL != m_pLock) 123 | m_pLock->lock(); 124 | } 125 | 126 | CAutoLock::~CAutoLock() 127 | { 128 | if(NULL != m_pLock) 129 | m_pLock->unlock(); 130 | } 131 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/2-im_new/Lock.h: -------------------------------------------------------------------------------- 1 | /*================================================================ 2 | * Copyright (C) 2014 All rights reserved. 3 | * 4 | * 文件名称:Lock.h 5 | * 创 建 者:Zhang Yuanhao 6 | * 邮 箱:bluefoxah@gmail.com 7 | * 创建日期:2014年09月10日 8 | * 描 述: 9 | * 10 | #pragma once 11 | ================================================================*/ 12 | 13 | #ifndef __LOCK_H__ 14 | #define __LOCK_H__ 15 | 16 | #include "ostype.h" 17 | 18 | class CLock 19 | { 20 | public: 21 | CLock(); 22 | virtual ~CLock(); 23 | void lock(); 24 | void unlock(); 25 | pthread_mutex_t& getMutex() { return m_lock; } 26 | #ifndef _WIN32 27 | virtual bool try_lock(); 28 | #endif 29 | private: 30 | #ifdef _WIN32 31 | CRITICAL_SECTION m_critical_section; 32 | #else 33 | pthread_mutex_t m_lock; 34 | #endif 35 | }; 36 | 37 | #ifndef _WIN32 38 | class CRWLock 39 | { 40 | public: 41 | CRWLock(); 42 | virtual ~CRWLock(); 43 | void rlock(); 44 | void wlock(); 45 | void unlock(); 46 | bool try_rlock(); 47 | bool try_wlock(); 48 | private: 49 | pthread_rwlock_t m_lock; 50 | }; 51 | 52 | class CAutoRWLock 53 | { 54 | public: 55 | CAutoRWLock(CRWLock* pLock, bool bRLock = true); 56 | virtual ~CAutoRWLock(); 57 | private: 58 | CRWLock* m_pLock; 59 | }; 60 | 61 | #endif 62 | 63 | class CAutoLock 64 | { 65 | public: 66 | CAutoLock(CLock* pLock); 67 | virtual ~CAutoLock(); 68 | private: 69 | CLock* m_pLock; 70 | }; 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/2-im_new/client_im: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.3.2protobuf/2-protobuf/2-im_new/client_im -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/2-im_new/create.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | SRC_DIR=./ 3 | DST_DIR=./ 4 | 5 | #C++ 6 | mkdir -p $DST_DIR/cpp 7 | protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/*.proto 8 | 9 | 10 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/2-im_new/msg.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package Im; 3 | message helloworld 4 | { 5 | int32 id = 1; 6 | string str = 2; 7 | int32 opt = 3; 8 | } 9 | message worldhello 10 | { 11 | int32 id = 1; 12 | string str = 2; 13 | int32 otp = 3; 14 | } -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/2-im_new/server_im: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.3.2protobuf/2-protobuf/2-im_new/server_im -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/2-im_new/util.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTIL_H__ 2 | #define __UTIL_H__ 3 | 4 | #define _CRT_SECURE_NO_DEPRECATE // remove warning C4996, 5 | 6 | #include "ostype.h" 7 | #include "UtilPdu.h" 8 | #include "Lock.h" 9 | #include 10 | #include 11 | #include 12 | #ifndef _WIN32 13 | #include 14 | #endif 15 | 16 | #include 17 | #include 18 | 19 | 20 | #ifdef _WIN32 21 | #define snprintf sprintf_s 22 | #else 23 | #include 24 | #include 25 | #include 26 | #include 27 | #endif 28 | 29 | #define NOTUSED_ARG(v) ((void)v) // used this to remove warning C4100, unreferenced parameter 30 | 31 | /// yunfan modify end 32 | class CRefObject 33 | { 34 | public: 35 | CRefObject(); 36 | virtual ~CRefObject(); 37 | 38 | void SetLock(CLock* lock) { m_lock = lock; } 39 | void AddRef(); 40 | void ReleaseRef(); 41 | private: 42 | int m_refCount; 43 | CLock* m_lock; 44 | }; 45 | 46 | #define LOG_MODULE_IM "IM" 47 | 48 | 49 | 50 | // Add By ZhangYuanhao 2015-01-14 For log show the file name not the full path + filename 51 | #define __FILENAME__ (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1):__FILE__) 52 | #if defined(_WIN32) || defined(_WIN64) 53 | #define log(fmt, ...) 54 | #else 55 | #define log(fmt, args...) 56 | #define log_debug(fmt, args...) 57 | #define log_warn(fmt, args...) 58 | #define log_error(fmt, args...) 59 | #define log_fatal(fmt, args...) 60 | #endif 61 | //#define log(fmt, ...) g_imlog.Info("<%s>\t<%d>\t<%s>,"+fmt, __FILENAME__, __LINE__, __FUNCTION__, ##__VA_ARGS__) 62 | 63 | uint64_t get_tick_count(); 64 | void util_sleep(uint32_t millisecond); 65 | 66 | 67 | class CStrExplode 68 | { 69 | public: 70 | CStrExplode(char* str, char seperator); 71 | virtual ~CStrExplode(); 72 | 73 | uint32_t GetItemCnt() { return m_item_cnt; } 74 | char* GetItem(uint32_t idx) { return m_item_list[idx]; } 75 | private: 76 | uint32_t m_item_cnt; 77 | char** m_item_list; 78 | }; 79 | 80 | char* replaceStr(char* pSrc, char oldChar, char newChar); 81 | string int2string(uint32_t user_id); 82 | uint32_t string2int(const string& value); 83 | void replace_mark(string& str, string& new_value, uint32_t& begin_pos); 84 | void replace_mark(string& str, uint32_t new_value, uint32_t& begin_pos); 85 | 86 | void writePid(); 87 | inline unsigned char toHex(const unsigned char &x); 88 | inline unsigned char fromHex(const unsigned char &x); 89 | string URLEncode(const string &sIn); 90 | string URLDecode(const string &sIn); 91 | 92 | 93 | int64_t get_file_size(const char *path); 94 | const char* memfind(const char *src_str,size_t src_len, const char *sub_str, size_t sub_len, bool flag = true); 95 | 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/3-person/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "xstring": "cpp", 4 | "iostream": "cpp", 5 | "algorithm": "cpp", 6 | "cmath": "cpp", 7 | "cstddef": "cpp", 8 | "cstdint": "cpp", 9 | "cstdio": "cpp", 10 | "cstdlib": "cpp", 11 | "cstring": "cpp", 12 | "cwchar": "cpp", 13 | "exception": "cpp", 14 | "initializer_list": "cpp", 15 | "ios": "cpp", 16 | "iosfwd": "cpp", 17 | "istream": "cpp", 18 | "limits": "cpp", 19 | "new": "cpp", 20 | "ostream": "cpp", 21 | "stdexcept": "cpp", 22 | "streambuf": "cpp", 23 | "string": "cpp", 24 | "system_error": "cpp", 25 | "type_traits": "cpp", 26 | "typeinfo": "cpp", 27 | "utility": "cpp", 28 | "xfacet": "cpp", 29 | "xiosbase": "cpp", 30 | "xlocale": "cpp", 31 | "xlocinfo": "cpp", 32 | "xlocnum": "cpp", 33 | "xmemory": "cpp", 34 | "xmemory0": "cpp", 35 | "xstddef": "cpp", 36 | "xtr1common": "cpp", 37 | "xutility": "cpp" 38 | } 39 | } -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/3-person/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | project (pb) 4 | 5 | ADD_DEFINITIONS(-W -Wall -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DAC_HAS_INFO 6 | -DAC_HAS_WARNING -DAC_HAS_ERROR -DAC_HAS_CRITICAL -DTIXML_USE_STL 7 | -DAC_HAS_DEBUG -DLINUX_DAEMON -std=c++11) 8 | 9 | set(pb_srcs 10 | IM.BaseDefine.pb.cc 11 | IM.Login.pb.cc 12 | ) 13 | 14 | 15 | add_executable(pb_speed pb_speed.cpp ${pb_srcs}) 16 | add_executable(code_test code_test.cpp ${pb_srcs}) 17 | TARGET_LINK_LIBRARIES(pb_speed protobuf pthread) 18 | TARGET_LINK_LIBRARIES(code_test protobuf pthread) 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/3-person/IM.BaseDefine.pb.cc: -------------------------------------------------------------------------------- 1 | // Generated by the protocol buffer compiler. DO NOT EDIT! 2 | // source: IM.BaseDefine.proto 3 | 4 | #include "IM.BaseDefine.pb.h" 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | // @@protoc_insertion_point(includes) 13 | #include 14 | namespace IM { 15 | namespace BaseDefine { 16 | } // namespace BaseDefine 17 | } // namespace IM 18 | namespace IM { 19 | namespace BaseDefine { 20 | bool PhoneType_IsValid(int value) { 21 | switch (value) { 22 | case 0: 23 | case 1: 24 | case 2: 25 | return true; 26 | default: 27 | return false; 28 | } 29 | } 30 | 31 | 32 | // @@protoc_insertion_point(namespace_scope) 33 | } // namespace BaseDefine 34 | } // namespace IM 35 | PROTOBUF_NAMESPACE_OPEN 36 | PROTOBUF_NAMESPACE_CLOSE 37 | 38 | // @@protoc_insertion_point(global_scope) 39 | #include 40 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/3-person/code_test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.3.2protobuf/2-protobuf/3-person/code_test -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/3-person/proto/IM.BaseDefine.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package IM.BaseDefine; 3 | 4 | option optimize_for = LITE_RUNTIME; 5 | 6 | enum PhoneType{ 7 | PHONE_DEFAULT = 0x0; 8 | PHONE_HOME = 0x0001; // 家庭电话 9 | PHONE_WORK = 0x0002; // 工作电话 10 | } -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/3-person/proto/IM.Login.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; // syntax 版本2/3是不一样,默认是proto2 2 | package IM.Login; // package 生成对应的C++命名空间 IM::Login:: 3 | import "IM.BaseDefine.proto"; // import 引用其他proto文件 4 | option optimize_for = LITE_RUNTIME; 5 | 6 | // message关键字 代表一个对象 7 | message Phone{ 8 | string number = 1; // = 1是什么?默认值 9 | IM.BaseDefine.PhoneType phone_type = 2; 10 | } 11 | 12 | message Book{ 13 | string name = 1; 14 | float price = 2; 15 | } 16 | 17 | message Person{ 18 | string name = 1; 19 | int32 age = 2; 20 | repeated string languages = 3; 21 | Phone phone = 4; 22 | repeated Book books = 5; // repeated 重复, 可以嵌套对象 23 | bool vip = 6; 24 | string address = 7; 25 | } 26 | 27 | //使用T开头测试 28 | message TInt32{ 29 | int32 int1 = 1; 30 | } 31 | 32 | message TString{ 33 | string str1 = 1; 34 | } 35 | 36 | 37 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/3-person/proto/create.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # proto文件在哪里 3 | SRC_DIR=./ 4 | # .h .cc输出到哪里 5 | DST_DIR=../ 6 | 7 | #C++ 8 | protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/*.proto 9 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/4-addressbook/add_person: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.3.2protobuf/2-protobuf/4-addressbook/add_person -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/4-addressbook/addressbook.proto: -------------------------------------------------------------------------------- 1 | // See README.txt for information and build instructions. 2 | // 3 | // Note: START and END tags are used in comments to define sections used in 4 | // tutorials. They are not part of the syntax for Protocol Buffers. 5 | // 6 | // To get an in-depth walkthrough of this file and the related examples, see: 7 | // https://developers.google.com/protocol-buffers/docs/tutorials 8 | 9 | // [START declaration] 10 | syntax = "proto3"; // proto2 11 | package tutorial; // package类似C++命名空间 12 | // 可以引用本地的,也可以引用include里面的 13 | import "google/protobuf/timestamp.proto"; // 已经写好的proto文件是可以引用 14 | // [END declaration] 15 | 16 | //protoc -I=/路径1 --cpp_out=./路径2 /路径1/addressbook.proto 17 | //路径1为.proto所在的路径 18 | //路径2为.cc和.h生成的位置 19 | //将指定proto文件生成.pb.cc和.pb.h 20 | //protoc -I=./ --cpp_out=./ addressbook.proto 21 | //将对应目录的所有proto文件生成.pb.cc和.pb.h 22 | //protoc -I=./ --cpp_out=./ *.proto 23 | 24 | 25 | // [START java_declaration] 26 | option java_package = "com.example.tutorial"; 27 | option java_outer_classname = "AddressBookProtos"; 28 | // [END java_declaration] 29 | 30 | // [START csharp_declaration] 31 | option csharp_namespace = "Google.Protobuf.Examples.AddressBook"; 32 | // [END csharp_declaration] 33 | 34 | // [START messages] 35 | message Person { // message类似C++的class 36 | string name = 1; 37 | int32 id = 2; // Unique ID number for this person. 38 | string email = 3; 39 | 40 | enum PhoneType { // enum 枚举类型 41 | MOBILE = 0; 42 | HOME = 1; 43 | WORK = 2; 44 | } 45 | 46 | message PhoneNumber { 47 | string number = 1; // 字符串 电话号码 48 | PhoneType type = 2; // 49 | } 50 | 51 | repeated PhoneNumber phones = 4; // 重复0~多个,一个人有多个电话 52 | 53 | google.protobuf.Timestamp last_updated = 5; // import "google/protobuf/timestamp.proto" 54 | } 55 | 56 | // Our address book file is just one of these. 57 | message AddressBook { 58 | repeated Person people = 1; // 电话簿有多人的电话 59 | } 60 | // [END messages] 61 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/4-addressbook/book: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.3.2protobuf/2-protobuf/4-addressbook/book -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/4-addressbook/core: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.3.2protobuf/2-protobuf/4-addressbook/core -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/4-addressbook/list_people: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.3.2protobuf/2-protobuf/4-addressbook/list_people -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/5-codec/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "xstring": "cpp", 4 | "iostream": "cpp", 5 | "algorithm": "cpp", 6 | "cmath": "cpp", 7 | "cstddef": "cpp", 8 | "cstdint": "cpp", 9 | "cstdio": "cpp", 10 | "cstdlib": "cpp", 11 | "cstring": "cpp", 12 | "cwchar": "cpp", 13 | "exception": "cpp", 14 | "initializer_list": "cpp", 15 | "ios": "cpp", 16 | "iosfwd": "cpp", 17 | "istream": "cpp", 18 | "limits": "cpp", 19 | "new": "cpp", 20 | "ostream": "cpp", 21 | "stdexcept": "cpp", 22 | "streambuf": "cpp", 23 | "string": "cpp", 24 | "system_error": "cpp", 25 | "type_traits": "cpp", 26 | "typeinfo": "cpp", 27 | "utility": "cpp", 28 | "xfacet": "cpp", 29 | "xiosbase": "cpp", 30 | "xlocale": "cpp", 31 | "xlocinfo": "cpp", 32 | "xlocnum": "cpp", 33 | "xmemory": "cpp", 34 | "xmemory0": "cpp", 35 | "xstddef": "cpp", 36 | "xtr1common": "cpp", 37 | "xutility": "cpp", 38 | "atomic": "cpp", 39 | "bit": "cpp", 40 | "cctype": "cpp", 41 | "clocale": "cpp", 42 | "compare": "cpp", 43 | "concepts": "cpp", 44 | "ctime": "cpp", 45 | "iterator": "cpp", 46 | "memory": "cpp", 47 | "tuple": "cpp", 48 | "list": "cpp", 49 | "vector": "cpp", 50 | "xhash": "cpp", 51 | "xtree": "cpp", 52 | "chrono": "cpp", 53 | "functional": "cpp", 54 | "map": "cpp", 55 | "mutex": "cpp", 56 | "ratio": "cpp", 57 | "set": "cpp", 58 | "sstream": "cpp", 59 | "stop_token": "cpp", 60 | "thread": "cpp", 61 | "unordered_map": "cpp", 62 | "unordered_set": "cpp" 63 | } 64 | } -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/5-codec/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | project (pb) 4 | 5 | ADD_DEFINITIONS(-W -Wall -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DAC_HAS_INFO 6 | -DAC_HAS_WARNING -DAC_HAS_ERROR -DAC_HAS_CRITICAL -DTIXML_USE_STL 7 | -DAC_HAS_DEBUG -DLINUX_DAEMON -std=c++11) 8 | 9 | set(pb_srcs 10 | Codec.pb.cc 11 | ) 12 | 13 | add_executable(code_test code_test.cpp ${pb_srcs}) 14 | TARGET_LINK_LIBRARIES(code_test protobuf pthread) 15 | # TARGET_LINK_LIBRARIES(code_test protobuf-lite pthread) 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/5-codec/Codec.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; // syntax 版本2/3是不一样,默认是proto2 2 | package Codec; // package 生成对应的C++命名空间 Codec:: 3 | //option optimize_for = LITE_RUNTIME; 4 | 5 | //protoc -I=./ --cpp_out=./ Codec.proto 6 | // Type = 0 起始 varint 7 | 8 | //使用T开头测试 9 | message Tint32{ 10 | int32 n1 = 1; 11 | } 12 | 13 | 14 | message Tint64{ 15 | int64 n1 = 1; 16 | } 17 | 18 | message Tuint32{ 19 | uint32 n1 = 1; 20 | } 21 | 22 | message Tuint64{ 23 | uint64 n1 = 1; 24 | } 25 | 26 | message Tsint32{ 27 | sint32 n1 = 1; 28 | } 29 | 30 | message Tsint64{ 31 | sint64 n1 = 1; 32 | } 33 | 34 | 35 | message Tbool{ 36 | bool n1 = 1; 37 | } 38 | 39 | enum PhoneType{ 40 | PHONE_DEFAULT = 0x0; 41 | PHONE_HOME = 0x0001; // 家庭电话 42 | PHONE_WORK = 0x0002; // 工作电话 43 | } 44 | message Tenum{ 45 | PhoneType n1 = 1; 46 | } 47 | // Type = 0 结束 48 | 49 | // Type = 1 起始 64bit 50 | message Tfixed64{ 51 | fixed64 n1 = 1; 52 | } 53 | 54 | message Tsfixed64{ 55 | sfixed64 n1 = 1; 56 | } 57 | 58 | message Tdouble{ 59 | double n1 = 1; 60 | } 61 | 62 | 63 | // Type = 1 结束 64 | 65 | // Type = 2 起始 length delimited 66 | 67 | message Tstring{ 68 | string n1 = 1; 69 | } 70 | 71 | message Tbytes{ 72 | bytes n1 = 1; 73 | } 74 | 75 | // 嵌套消息 76 | message Tembeddedmessages{ 77 | message TMsg { 78 | int32 n1 = 1; 79 | } 80 | 81 | TMsg n1 = 1; 82 | } 83 | 84 | message TRepeatedfields{ 85 | repeated int32 n1 = 1; 86 | repeated Tbytes n2 = 2; 87 | } 88 | 89 | // Type = 2 结束 90 | 91 | // Type = 5 起始 92 | message Tfixed32{ 93 | fixed32 n1 = 1; 94 | } 95 | 96 | message Tsfixed32{ 97 | sfixed32 n1 = 1; 98 | } 99 | 100 | message Tfloat{ 101 | float n1 = 1; 102 | } 103 | 104 | 105 | message THasitem{ 106 | int32 n1_int32 = 3000; 107 | int32 n2_int32 = 2; 108 | uint32 n3_uint32 = 3; 109 | sint32 n4_sint32 = 4; 110 | fixed32 n5_fixed32 = 5; 111 | float n6_float = 6; 112 | bytes n7_bytes = 7; 113 | Tbytes n8_Tbytes = 8; 114 | int32 n9_int32 = 9; 115 | } 116 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/5-codec/code_test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/3.3.2protobuf/2-protobuf/5-codec/code_test -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/5-codec/proto/IM.BaseDefine.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package IM.BaseDefine; 3 | 4 | option optimize_for = LITE_RUNTIME; 5 | 6 | enum PhoneType{ 7 | PHONE_DEFAULT = 0x0; 8 | PHONE_HOME = 0x0001; // 家庭电话 9 | PHONE_WORK = 0x0002; // 工作电话 10 | } -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/5-codec/proto/create.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # proto文件在哪里 3 | SRC_DIR=./ 4 | # .h .cc输出到哪里 5 | DST_DIR=../ 6 | 7 | #C++ 8 | protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/*.proto 9 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/5-codec/protobuf/compiler/js/well_known_types_embed.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | #ifndef GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__ 32 | #define GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__ 33 | 34 | #include 35 | 36 | struct FileToc { 37 | const char* name; 38 | const char* data; 39 | }; 40 | 41 | extern struct FileToc well_known_types_js[]; 42 | 43 | #endif // GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__ 44 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/5-codec/protobuf/empty.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option go_package = "github.com/golang/protobuf/ptypes/empty"; 37 | option java_package = "com.google.protobuf"; 38 | option java_outer_classname = "EmptyProto"; 39 | option java_multiple_files = true; 40 | option objc_class_prefix = "GPB"; 41 | option cc_enable_arenas = true; 42 | 43 | // A generic empty message that you can re-use to avoid defining duplicated 44 | // empty messages in your APIs. A typical example is to use it as the request 45 | // or the response type of an API method. For instance: 46 | // 47 | // service Foo { 48 | // rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); 49 | // } 50 | // 51 | // The JSON representation for `Empty` is empty JSON object `{}`. 52 | message Empty {} 53 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/5-codec/protobuf/generated_enum_util.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | #ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__ 32 | #define GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__ 33 | 34 | #include 35 | 36 | #ifdef SWIG 37 | #error "You cannot SWIG proto headers" 38 | #endif 39 | 40 | namespace google { 41 | namespace protobuf { 42 | 43 | // This type trait can be used to cause templates to only match proto2 enum 44 | // types. 45 | template 46 | struct is_proto_enum : ::std::false_type {}; 47 | 48 | } // namespace protobuf 49 | } // namespace google 50 | 51 | #endif // GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__ 52 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/5-codec/protobuf/io/strtod.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // A locale-independent version of strtod(), used to parse floating 32 | // point default values in .proto files, where the decimal separator 33 | // is always a dot. 34 | 35 | #ifndef GOOGLE_PROTOBUF_IO_STRTOD_H__ 36 | #define GOOGLE_PROTOBUF_IO_STRTOD_H__ 37 | 38 | namespace google { 39 | namespace protobuf { 40 | namespace io { 41 | 42 | // A locale-independent version of the standard strtod(), which always 43 | // uses a dot as the decimal separator. 44 | double NoLocaleStrtod(const char* str, char** endptr); 45 | 46 | // Casts a double value to a float value. If the value is outside of the 47 | // representable range of float, it will be converted to positive or negative 48 | // infinity. 49 | float SafeDoubleToFloat(double value); 50 | 51 | } // namespace io 52 | } // namespace protobuf 53 | } // namespace google 54 | 55 | #endif // GOOGLE_PROTOBUF_IO_STRTOD_H__ 56 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/5-codec/protobuf/port.h: -------------------------------------------------------------------------------- 1 | #ifndef THIRD_PARTY_PROTOBUF_TESTING_PROTOBUF_SRC_GOOGLE_PROTOBUF_PORT_H_ 2 | #define THIRD_PARTY_PROTOBUF_TESTING_PROTOBUF_SRC_GOOGLE_PROTOBUF_PORT_H_ 3 | 4 | #include 5 | 6 | #endif // THIRD_PARTY_PROTOBUF_TESTING_PROTOBUF_SRC_GOOGLE_PROTOBUF_PORT_H_ 7 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/5-codec/protobuf/source_context.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option java_package = "com.google.protobuf"; 37 | option java_outer_classname = "SourceContextProto"; 38 | option java_multiple_files = true; 39 | option objc_class_prefix = "GPB"; 40 | option go_package = "google.golang.org/genproto/protobuf/source_context;source_context"; 41 | 42 | // `SourceContext` represents information about the source of a 43 | // protobuf element, like the file in which it is defined. 44 | message SourceContext { 45 | // The path-qualified name of the .proto file that contained the associated 46 | // protobuf element. For example: `"google/protobuf/source_context.proto"`. 47 | string file_name = 1; 48 | } 49 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/5-codec/protobuf/stubs/once.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | #ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__ 32 | #define GOOGLE_PROTOBUF_STUBS_ONCE_H__ 33 | 34 | #include 35 | #include 36 | 37 | #include 38 | 39 | namespace google { 40 | namespace protobuf { 41 | namespace internal { 42 | 43 | using once_flag = std::once_flag; 44 | template 45 | void call_once(Args&&... args ) { 46 | std::call_once(std::forward(args)...); 47 | } 48 | 49 | } // namespace internal 50 | } // namespace protobuf 51 | } // namespace google 52 | 53 | #include 54 | 55 | #endif // GOOGLE_PROTOBUF_STUBS_ONCE_H__ 56 | -------------------------------------------------------------------------------- /3.3.2protobuf/2-protobuf/5-codec/protobuf/util/type_resolver_util.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Defines utilities for the TypeResolver. 32 | 33 | #ifndef GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__ 34 | #define GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__ 35 | 36 | #include 37 | 38 | namespace google { 39 | namespace protobuf { 40 | class DescriptorPool; 41 | namespace util { 42 | class TypeResolver; 43 | 44 | #include 45 | 46 | // Creates a TypeResolver that serves type information in the given descriptor 47 | // pool. Caller takes ownership of the returned TypeResolver. 48 | PROTOBUF_EXPORT TypeResolver* NewTypeResolverForDescriptorPool( 49 | const std::string& url_prefix, const DescriptorPool* pool); 50 | 51 | } // namespace util 52 | } // namespace protobuf 53 | } // namespace google 54 | 55 | #include 56 | 57 | #endif // GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__ 58 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 前言 2 | 3 | 源码与文章同步更新 4 | 5 | CSDN cheems~ :https://gopher.blog.csdn.net/ 6 | 7 | 掘金 GopherWxf : https://juejin.cn/user/3259393012930264 8 | 9 | 知乎 清风 :https://www.zhihu.com/people/gopherwxf 10 | -------------------------------------------------------------------------------- /文件服务器项目/day1fastdfs/fdfs_upload_file.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 68725 on 2022/9/5. 3 | // 4 | 5 | #ifndef FDFS_UPLOAD_FILE_H 6 | #define FDFS_UPLOAD_FILE_H 7 | 8 | extern int upload_file1(const char *confFile, const char *uploadFile, char *fileID, int size); 9 | 10 | extern int upload_file2(const char *confFile, const char *myFile, char *fileID); 11 | 12 | #endif //FDFS_UPLOAD_FILE_H 13 | -------------------------------------------------------------------------------- /文件服务器项目/day1fastdfs/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "fdfs_upload_file.h" 8 | 9 | int main() { 10 | char fildID[1024] = {0}; 11 | upload_file1("/etc/fdfs/client.conf", "main.c", fildID, sizeof(fildID)); 12 | printf("Multiprocess upload_file1 fildID:%s\n", fildID); 13 | printf("=================================\n"); 14 | upload_file2("/etc/fdfs/client.conf", "main.c", fildID); 15 | printf("Call API upload_file2 fildID:%s\n", fildID); 16 | } -------------------------------------------------------------------------------- /文件服务器项目/day2redis/myredis.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | // 1. 连接redis服务器 7 | redisContext* c = redisConnect("127.0.0.1", 6379); 8 | if (c->err != 0) 9 | { 10 | return -1; 11 | } 12 | // 2. 执行redis命令 13 | void *prt = redisCommand(c, "hmset user userName zhang3 passwd 123456 age 23 sex man"); 14 | redisReply* ply = (redisReply*)prt; 15 | if(ply->type == 5) 16 | { 17 | // 状态输出 18 | printf("状态: %s\n", ply->str); 19 | } 20 | freeReplyObject(ply); 21 | 22 | // 3. 从数据库中读数据 23 | prt = redisCommand(c, "hgetall user"); 24 | ply = (redisReply*)prt; 25 | if(ply->type == 2) 26 | { 27 | // 遍历 28 | for(int i=0; ielements; i+=2) 29 | { 30 | printf("key: %s, value: %s\n", ply->element[i]->str, ply->element[i+1]->str); 31 | } 32 | } 33 | freeReplyObject(ply); 34 | 35 | redisFree(c); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /文件服务器项目/day2redis/redis命令参考官方文档中文版.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/文件服务器项目/day2redis/redis命令参考官方文档中文版.pdf -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/Nginx配置说明.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/文件服务器项目/day3nginx/Nginx配置说明.doc -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/SwitchHosts/SwitchHosts.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/文件服务器项目/day3nginx/SwitchHosts/SwitchHosts.exe -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/SwitchHosts/configs.json: -------------------------------------------------------------------------------- 1 | {"hostses": ["0.hosts"]} -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/SwitchHosts/hosts/0.hosts: -------------------------------------------------------------------------------- 1 | #@SwitchHosts! {"url": null, "icon_idx": 0, "title": "test"} 2 | # test 3 | 4 | 5 | 192.168.109.101 ubuntu101to102.com 6 | 192.168.109.101 ubuntu101to103.com 7 | 192.168.109.101 reverse.proxy.com 8 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/SwitchHosts/hosts/0.hosts.backup_switchhosts: -------------------------------------------------------------------------------- 1 | #@SwitchHosts! {"url": null, "icon_idx": 0, "title": "121212"} 2 | # 121212 3 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/SwitchHosts/hosts/1.hosts.backup_switchhosts: -------------------------------------------------------------------------------- 1 | #@SwitchHosts! {"url": null, "icon_idx": 0, "title": "123"} 2 | # 123 3 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/SwitchHosts/hosts/COMMON.hosts: -------------------------------------------------------------------------------- 1 | #@SwitchHosts! {"url": null, "icon_idx": 0, "title": "COMMON.hosts"} 2 | # common 3 | #公用host 4 | 127.0.0.1 www.xmind.net 5 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/SwitchHosts/hosts/COMMON.hosts.backup_switchhosts: -------------------------------------------------------------------------------- 1 | # common -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/conf/fastcgi.conf: -------------------------------------------------------------------------------- 1 | 2 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 3 | fastcgi_param QUERY_STRING $query_string; 4 | fastcgi_param REQUEST_METHOD $request_method; 5 | fastcgi_param CONTENT_TYPE $content_type; 6 | fastcgi_param CONTENT_LENGTH $content_length; 7 | 8 | fastcgi_param SCRIPT_NAME $fastcgi_script_name; 9 | fastcgi_param REQUEST_URI $request_uri; 10 | fastcgi_param DOCUMENT_URI $document_uri; 11 | fastcgi_param DOCUMENT_ROOT $document_root; 12 | fastcgi_param SERVER_PROTOCOL $server_protocol; 13 | fastcgi_param REQUEST_SCHEME $scheme; 14 | fastcgi_param HTTPS $https if_not_empty; 15 | 16 | fastcgi_param GATEWAY_INTERFACE CGI/1.1; 17 | fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; 18 | 19 | fastcgi_param REMOTE_ADDR $remote_addr; 20 | fastcgi_param REMOTE_PORT $remote_port; 21 | fastcgi_param SERVER_ADDR $server_addr; 22 | fastcgi_param SERVER_PORT $server_port; 23 | fastcgi_param SERVER_NAME $server_name; 24 | 25 | # PHP only, required if PHP was built with --enable-force-cgi-redirect 26 | fastcgi_param REDIRECT_STATUS 200; 27 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/conf/fastcgi_params: -------------------------------------------------------------------------------- 1 | 2 | fastcgi_param QUERY_STRING $query_string; 3 | fastcgi_param REQUEST_METHOD $request_method; 4 | fastcgi_param CONTENT_TYPE $content_type; 5 | fastcgi_param CONTENT_LENGTH $content_length; 6 | 7 | fastcgi_param SCRIPT_NAME $fastcgi_script_name; 8 | fastcgi_param REQUEST_URI $request_uri; 9 | fastcgi_param DOCUMENT_URI $document_uri; 10 | fastcgi_param DOCUMENT_ROOT $document_root; 11 | fastcgi_param SERVER_PROTOCOL $server_protocol; 12 | fastcgi_param REQUEST_SCHEME $scheme; 13 | fastcgi_param HTTPS $https if_not_empty; 14 | 15 | fastcgi_param GATEWAY_INTERFACE CGI/1.1; 16 | fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; 17 | 18 | fastcgi_param REMOTE_ADDR $remote_addr; 19 | fastcgi_param REMOTE_PORT $remote_port; 20 | fastcgi_param SERVER_ADDR $server_addr; 21 | fastcgi_param SERVER_PORT $server_port; 22 | fastcgi_param SERVER_NAME $server_name; 23 | 24 | # PHP only, required if PHP was built with --enable-force-cgi-redirect 25 | fastcgi_param REDIRECT_STATUS 200; 26 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/conf/scgi_params: -------------------------------------------------------------------------------- 1 | 2 | scgi_param REQUEST_METHOD $request_method; 3 | scgi_param REQUEST_URI $request_uri; 4 | scgi_param QUERY_STRING $query_string; 5 | scgi_param CONTENT_TYPE $content_type; 6 | 7 | scgi_param DOCUMENT_URI $document_uri; 8 | scgi_param DOCUMENT_ROOT $document_root; 9 | scgi_param SCGI 1; 10 | scgi_param SERVER_PROTOCOL $server_protocol; 11 | scgi_param REQUEST_SCHEME $scheme; 12 | scgi_param HTTPS $https if_not_empty; 13 | 14 | scgi_param REMOTE_ADDR $remote_addr; 15 | scgi_param REMOTE_PORT $remote_port; 16 | scgi_param SERVER_PORT $server_port; 17 | scgi_param SERVER_NAME $server_name; 18 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/conf/uwsgi_params: -------------------------------------------------------------------------------- 1 | 2 | uwsgi_param QUERY_STRING $query_string; 3 | uwsgi_param REQUEST_METHOD $request_method; 4 | uwsgi_param CONTENT_TYPE $content_type; 5 | uwsgi_param CONTENT_LENGTH $content_length; 6 | 7 | uwsgi_param REQUEST_URI $request_uri; 8 | uwsgi_param PATH_INFO $document_uri; 9 | uwsgi_param DOCUMENT_ROOT $document_root; 10 | uwsgi_param SERVER_PROTOCOL $server_protocol; 11 | uwsgi_param REQUEST_SCHEME $scheme; 12 | uwsgi_param HTTPS $https if_not_empty; 13 | 14 | uwsgi_param REMOTE_ADDR $remote_addr; 15 | uwsgi_param REMOTE_PORT $remote_port; 16 | uwsgi_param SERVER_PORT $server_port; 17 | uwsgi_param SERVER_NAME $server_name; 18 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/contrib/README: -------------------------------------------------------------------------------- 1 | 2 | geo2nginx.pl by Andrei Nigmatulin 3 | 4 | The perl script to convert CSV geoip database ( free download 5 | at http://www.maxmind.com/app/geoip_country ) to format, suitable 6 | for use by the ngx_http_geo_module. 7 | 8 | 9 | unicode2nginx by Maxim Dounin 10 | 11 | The perl script to convert unicode mappings ( available 12 | at http://www.unicode.org/Public/MAPPINGS/ ) to the nginx 13 | configuration file format. 14 | Two generated full maps for windows-1251 and koi8-r. 15 | 16 | 17 | vim by Evan Miller 18 | 19 | Syntax highlighting of nginx configuration for vim, to be 20 | placed into ~/.vim/. 21 | 22 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/contrib/geo2nginx.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | # (c) Andrei Nigmatulin, 2005 4 | # 5 | # this script provided "as is", without any warranties. use it at your own risk. 6 | # 7 | # special thanx to Andrew Sitnikov for perl port 8 | # 9 | # this script converts CSV geoip database (free download at http://www.maxmind.com/app/geoip_country) 10 | # to format, suitable for use with nginx_http_geo module (http://sysoev.ru/nginx) 11 | # 12 | # for example, line with ip range 13 | # 14 | # "62.16.68.0","62.16.127.255","1041253376","1041268735","RU","Russian Federation" 15 | # 16 | # will be converted to four subnetworks: 17 | # 18 | # 62.16.68.0/22 RU; 19 | # 62.16.72.0/21 RU; 20 | # 62.16.80.0/20 RU; 21 | # 62.16.96.0/19 RU; 22 | 23 | 24 | use warnings; 25 | use strict; 26 | 27 | while( ){ 28 | if (/"[^"]+","[^"]+","([^"]+)","([^"]+)","([^"]+)"/){ 29 | print_subnets($1, $2, $3); 30 | } 31 | } 32 | 33 | sub print_subnets { 34 | my ($a1, $a2, $c) = @_; 35 | my $l; 36 | while ($a1 <= $a2) { 37 | for ($l = 0; ($a1 & (1 << $l)) == 0 && ($a1 + ((1 << ($l + 1)) - 1)) <= $a2; $l++){}; 38 | print long2ip($a1) . "/" . (32 - $l) . " " . $c . ";\n"; 39 | $a1 += (1 << $l); 40 | } 41 | } 42 | 43 | sub long2ip { 44 | my $ip = shift; 45 | 46 | my $str = 0; 47 | 48 | $str = ($ip & 255); 49 | 50 | $ip >>= 8; 51 | $str = ($ip & 255).".$str"; 52 | 53 | $ip >>= 8; 54 | $str = ($ip & 255).".$str"; 55 | 56 | $ip >>= 8; 57 | $str = ($ip & 255).".$str"; 58 | } 59 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/contrib/unicode2nginx/unicode-to-nginx.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | # Convert unicode mappings to nginx configuration file format. 4 | 5 | # You may find useful mappings in various places, including 6 | # unicode.org official site: 7 | # 8 | # http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT 9 | # http://www.unicode.org/Public/MAPPINGS/VENDORS/MISC/KOI8-R.TXT 10 | 11 | # Needs perl 5.6 or later. 12 | 13 | # Written by Maxim Dounin, mdounin@mdounin.ru 14 | 15 | ############################################################################### 16 | 17 | require 5.006; 18 | 19 | while (<>) { 20 | # Skip comments and empty lines 21 | 22 | next if /^#/; 23 | next if /^\s*$/; 24 | chomp; 25 | 26 | # Convert mappings 27 | 28 | if (/^\s*0x(..)\s*0x(....)\s*(#.*)/) { 29 | # Mapping "#" 30 | my $cs_code = $1; 31 | my $un_code = $2; 32 | my $un_name = $3; 33 | 34 | # Produce UTF-8 sequence from character code; 35 | 36 | my $un_utf8 = join('', 37 | map { sprintf("%02X", $_) } 38 | unpack("U0C*", pack("U", hex($un_code))) 39 | ); 40 | 41 | print " $cs_code $un_utf8 ; $un_name\n"; 42 | 43 | } else { 44 | warn "Unrecognized line: '$_'"; 45 | } 46 | } 47 | 48 | ############################################################################### 49 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/contrib/vim/ftdetect/nginx.vim: -------------------------------------------------------------------------------- 1 | au BufRead,BufNewFile *.nginx set ft=nginx 2 | au BufRead,BufNewFile */etc/nginx/* set ft=nginx 3 | au BufRead,BufNewFile */usr/local/nginx/conf/* set ft=nginx 4 | au BufRead,BufNewFile nginx.conf set ft=nginx 5 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/contrib/vim/ftplugin/nginx.vim: -------------------------------------------------------------------------------- 1 | setlocal commentstring=#\ %s 2 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/contrib/vim/indent/nginx.vim: -------------------------------------------------------------------------------- 1 | if exists("b:did_indent") 2 | finish 3 | endif 4 | let b:did_indent = 1 5 | 6 | setlocal indentexpr= 7 | 8 | " cindent actually works for nginx' simple file structure 9 | setlocal cindent 10 | " Just make sure that the comments are not reset as defs would be. 11 | setlocal cinkeys-=0# 12 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/docs/LICENSE: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2002-2017 Igor Sysoev 3 | * Copyright (C) 2011-2017 Nginx, Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 | * SUCH DAMAGE. 26 | */ 27 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/docs/README: -------------------------------------------------------------------------------- 1 | 2 | Documentation is available at http://nginx.org 3 | 4 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/docs/zlib.LICENSE: -------------------------------------------------------------------------------- 1 | (C) 1995-2017 Jean-loup Gailly and Mark Adler 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. 18 | 19 | Jean-loup Gailly Mark Adler 20 | jloup@gzip.org madler@alumni.caltech.edu 21 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/html/50x.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Error 5 | 12 | 13 | 14 |

An error occurred.

15 |

Sorry, the page you are looking for is currently unavailable.
16 | Please try again later.

17 |

If you are the system administrator of this resource then you should check 18 | the error log for details.

19 |

Faithfully yours, nginx.

20 | 21 | 22 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Welcome to nginx! 5 | 12 | 13 | 14 |

Welcome to nginx!

15 |

If you see this page, the nginx web server is successfully installed and 16 | working. Further configuration is required.

17 | 18 |

For online documentation and support please refer to 19 | nginx.org.
20 | Commercial support is available at 21 | nginx.com.

22 | 23 |

Thank you for using nginx.

24 | 25 | 26 | -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.12.0/nginx.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/文件服务器项目/day3nginx/nginx-1.12.0/nginx.exe -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/nginx-1.16.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/文件服务器项目/day3nginx/nginx-1.16.1.tar.gz -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/openssl-1.1.1g.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/文件服务器项目/day3nginx/openssl-1.1.1g.tar.gz -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/pcre-8.44.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/文件服务器项目/day3nginx/pcre-8.44.tar.gz -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/yundisk.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/文件服务器项目/day3nginx/yundisk.tar.gz -------------------------------------------------------------------------------- /文件服务器项目/day3nginx/zlib-1.2.11.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/文件服务器项目/day3nginx/zlib-1.2.11.tar.gz -------------------------------------------------------------------------------- /文件服务器项目/day4fastCGI/fcgi-2.4.1-SNAP-0910052249.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/文件服务器项目/day4fastCGI/fcgi-2.4.1-SNAP-0910052249.tar.gz -------------------------------------------------------------------------------- /文件服务器项目/day4fastCGI/spawn-fcgi-1.6.4.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/文件服务器项目/day4fastCGI/spawn-fcgi-1.6.4.tar.gz -------------------------------------------------------------------------------- /文件服务器项目/day4fastCGI/zyFile2.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/文件服务器项目/day4fastCGI/zyFile2.tar.gz -------------------------------------------------------------------------------- /文件服务器项目/day5nginx+fastDFS/fastdfs-nginx-module-1.22.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherWxf/c-c-linux-LearningCode/b02d8b02b0db204457a71c7ee72248b91a48ee96/文件服务器项目/day5nginx+fastDFS/fastdfs-nginx-module-1.22.tar.gz --------------------------------------------------------------------------------