简体   繁体   中英

How can C++ detect the current thread it's running on?

I'm using Flutter for Desktop and I'm calling a method on the engine from a separate thread. I get this error:

[FATAL:flutter/shell/common/shell.cc(808)] Check failed: task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread(). 

which comes from this line:

https://github.com/flutter/engine/blob/master/shell/common/shell.cc#L836

I confirmed that the error does not happen when I call the method from the same thread that the engine is created on.

So the error is telling me that I need to call this method from the same thread on where the engine was created

So how can C++ know which thread is calling a method?

I traced the task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread() call and it ends up in this:

https://github.com/flutter/engine/blob/master/fml/task_runner.cc#L41

but I couldn't understand what's happening.

So, to put things in simple code, let's say we have:

class Object{
public:
  void run() {
  //how can this run function know it's being called by t thread instead of main's thread?
  }
}


int main() {
  Object obj;
  std::thread t (obj.run);
  RunLoop();
}

Most OS's that support multi threading have system calls to get the thread ID of the current Thread.

Linux

Windows

This was standardized into a cross-platform solution in C++11

You can get the thread ID an object was created on in the constructor, and then compare it to the current thread ID that a function is called in.

To make this more concrete, I've made a class DetectsWhenOnDifferentThread which will print out different things when you call its DoThing function from a different thread than it was constructed on.

#include <thread>
#include <iostream>

class DetectsWhenOnDifferentThread {
 public:
  DetectsWhenOnDifferentThread()
      : thread_id_on_construction_(std::this_thread::get_id()) {}
  void DoThing() {
    if (std::this_thread::get_id() != thread_id_on_construction_) {
      std::cout << "I'm on the wrong thread!" << std::endl;
    } else {
      std::cout << "Thanks for using me on the proper thread." << std::endl;
    }
  }
  std::thread::id thread_id_on_construction_;
};

void ManipulateThing(DetectsWhenOnDifferentThread* thingy) {
  thingy->DoThing();
}

int main() {
  DetectsWhenOnDifferentThread thingy;
  thingy.DoThing();
  auto worker = std::thread(ManipulateThing, &thingy);
  worker.join();
}

Here's an example of compiling this code and running it:

$ g++ --version
g++ (Debian 9.2.1-8) 9.2.1 20190909
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ g++ -pthread ex.cc

$ ./a.out
Thanks for using me on the proper thread.
I'm on the wrong thread!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM