日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

muduo之Thread

發布時間:2025/6/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 muduo之Thread 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? ?muduo也對線程進行了封裝,下面看一下實現。

Thread.h

// Use of this source code is governed by a BSD-style license // that can be found in the License file. // // Author: Shuo Chen (chenshuo at chenshuo dot com)#ifndef MUDUO_BASE_THREAD_H #define MUDUO_BASE_THREAD_H#include "muduo/base/Atomic.h" #include "muduo/base/CountDownLatch.h" #include "muduo/base/Types.h"#include <functional> #include <memory> #include <pthread.h>namespace muduo {class Thread : noncopyable {public:typedef std::function<void ()> ThreadFunc;explicit Thread(ThreadFunc, const string& name = string());// FIXME: make it movable in C++11~Thread();void start();int join(); // return pthread_join()bool started() const { return started_; }// pthread_t pthreadId() const { return pthreadId_; }pid_t tid() const { return tid_; }const string& name() const { return name_; }static int numCreated() { return numCreated_.get(); }private:void setDefaultName();bool started_; //線程是否啟動bool joined_; //線程是否回收pthread_t pthreadId_;//線程IDpid_t tid_; //進程idThreadFunc func_;//線程回調函數string name_; //線程名稱CountDownLatch latch_;static AtomicInt32 numCreated_;//原子操作 };} // namespace muduo #endif // MUDUO_BASE_THREAD_H

Thread.cc

// Use of this source code is governed by a BSD-style license // that can be found in the License file. // // Author: Shuo Chen (chenshuo at chenshuo dot com)#include "muduo/base/Thread.h" #include "muduo/base/CurrentThread.h" #include "muduo/base/Exception.h" #include "muduo/base/Logging.h"#include <type_traits>#include <errno.h> #include <stdio.h> #include <unistd.h> #include <sys/prctl.h> #include <sys/syscall.h> #include <sys/types.h> #include <linux/unistd.h>namespace muduo { namespace detail {pid_t gettid() //獲取線程的進程ID {return static_cast<pid_t>(::syscall(SYS_gettid)); //真實的線程ID(不同進程中的線程ID可能相同)tid }void afterFork() {muduo::CurrentThread::t_cachedTid = 0;muduo::CurrentThread::t_threadName = "main";CurrentThread::tid();// no need to call pthread_atfork(NULL, NULL, &afterFork); }class ThreadNameInitializer {public:ThreadNameInitializer(){muduo::CurrentThread::t_threadName = "main";CurrentThread::tid();pthread_atfork(NULL, NULL, &afterFork);/*pthread_atfork(void (*prepare)(void),void (*parent)(void), void(*child)(void))prepare在父進程fork創建子進程之前調用,這里可以獲取父進程定義的所有鎖;child fork返回之前在子進程環境中調用,在這里unlock prepare獲得的鎖;parent fork創建了子進程以后,但在fork返回之前在父進程的進程環境中調用的,在這里對prepare獲得的鎖進行解鎖*/} };ThreadNameInitializer init;//C++中class和struct一樣,只是權限的區別 struct ThreadData //一個中間結構用來存放線程的數據 {typedef muduo::Thread::ThreadFunc ThreadFunc;ThreadFunc func_;string name_;pid_t* tid_;CountDownLatch* latch_;ThreadData(ThreadFunc func,const string& name,pid_t* tid,CountDownLatch* latch): func_(std::move(func)),name_(name),tid_(tid), //將tid緩存起來latch_(latch){ }void runInThread(){*tid_ = muduo::CurrentThread::tid();//調用tid()該tid已被緩存起來tid_ = NULL;latch_->countDown();latch_ = NULL;muduo::CurrentThread::t_threadName = name_.empty() ? "muduoThread" : name_.c_str();::prctl(PR_SET_NAME, muduo::CurrentThread::t_threadName);//prctl設置線程的名字try{func_();//運行線程運行函數muduo::CurrentThread::t_threadName = "finished";}catch (const Exception& ex)//Exception異常{muduo::CurrentThread::t_threadName = "crashed";fprintf(stderr, "exception caught in Thread %s\n", name_.c_str());fprintf(stderr, "reason: %s\n", ex.what());fprintf(stderr, "stack trace: %s\n", ex.stackTrace());abort();}catch (const std::exception& ex)//標準異常{muduo::CurrentThread::t_threadName = "crashed";fprintf(stderr, "exception caught in Thread %s\n", name_.c_str());fprintf(stderr, "reason: %s\n", ex.what());abort();}catch (...)//其他{muduo::CurrentThread::t_threadName = "crashed";fprintf(stderr, "unknown exception caught in Thread %s\n", name_.c_str());throw; // rethrow}} };void* startThread(void* obj) {ThreadData* data = static_cast<ThreadData*>(obj);data->runInThread();delete data;return NULL; }} // namespace detailvoid CurrentThread::cacheTid() {if (t_cachedTid == 0){t_cachedTid = detail::gettid();t_tidStringLength = snprintf(t_tidString, sizeof t_tidString, "%5d ", t_cachedTid);} }bool CurrentThread::isMainThread() {return tid() == ::getpid();//通過線程的pid和進程的pid做比較如果相同說明是主線程 }void CurrentThread::sleepUsec(int64_t usec) {struct timespec ts = { 0, 0 };ts.tv_sec = static_cast<time_t>(usec / Timestamp::kMicroSecondsPerSecond);ts.tv_nsec = static_cast<long>(usec % Timestamp::kMicroSecondsPerSecond * 1000);::nanosleep(&ts, NULL); }AtomicInt32 Thread::numCreated_;Thread::Thread(ThreadFunc func, const string& n): started_(false),joined_(false),pthreadId_(0),tid_(0),func_(std::move(func)),name_(n),latch_(1) {setDefaultName();//設置默認的名字 }Thread::~Thread() {if (started_ && !joined_) //已經啟動 && 不是分離狀態{pthread_detach(pthreadId_);//將線程設置為分離狀態,資源就自動回收了} }void Thread::setDefaultName() {int num = numCreated_.incrementAndGet();if (name_.empty()){char buf[32];snprintf(buf, sizeof buf, "Thread%d", num);name_ = buf;} }void Thread::start() {assert(!started_);started_ = true;// FIXME: move(func_)detail::ThreadData* data = new detail::ThreadData(func_, name_, &tid_, &latch_);if (pthread_create(&pthreadId_, NULL, &detail::startThread, data))//pthread_create成功返回0{started_ = false;delete data; // or no delete?LOG_SYSFATAL << "Failed in pthread_create";}else{//如果線程創建成功,主線程阻塞在這里,等待子線程執行threadFunc之前被喚醒latch_.wait();assert(tid_ > 0);} }int Thread::join() {assert(started_);assert(!joined_);joined_ = true;return pthread_join(pthreadId_, NULL); }} // namespace muduo

?

總結

以上是生活随笔為你收集整理的muduo之Thread的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。