Prosty przykład gwintowania w C++
Czy ktoś może zamieścić prosty przykład uruchamiania dwóch (obiektowych) wątków w C++.
Szukam rzeczywistych obiektów wątków C++, na których mogę rozszerzyć uruchamianie metod (lub coś podobnego) w przeciwieństwie do wywoływania biblioteki wątków w stylu C.
Update-pominąłem wszelkie specyficzne żądania systemu operacyjnego w nadziei, że ktokolwiek odpowiedział, odpowie za pomocą bibliotek wieloplatformowych. Wyrażam się jasno.
7 answers
Utwórz funkcję, którą wątek ma wykonać, np:
void task1(std::string msg)
{
std::cout << "task1 says: " << msg;
}
Teraz Utwórz thread
obiekt, który ostatecznie wywoła powyższą funkcję w następujący sposób:
std::thread t1(task1, "Hello");
(musisz #include <thread>
aby uzyskać dostęp do klasy std::thread
)
Argumentami konstruktora są funkcje, które wątek wykona, a następnie parametry funkcji. Wątek jest automatycznie uruchamiany podczas budowy.
Jeśli później chcesz poczekać, aż wątek zostanie zakończony, wykonując funkcję, wywołanie:
t1.join();
(połączenie oznacza, że wątek, który wywołał nowy wątek, będzie czekał na zakończenie wykonywania nowego wątku, zanim będzie kontynuował własne wykonanie).
Kod
#include <string>
#include <iostream>
#include <thread>
using namespace std;
// The function we want to execute on the new thread.
void task1(string msg)
{
cout << "task1 says: " << msg;
}
int main()
{
// Constructs the new thread and runs it. Does not block execution.
thread t1(task1, "Hello");
// Do other things...
// Makes the main thread wait for the new thread to finish execution, therefore blocks its own execution.
t1.join();
}
Więcej informacji o std::thread tutaj
- w GCC skompiluj za pomocą
-std=c++0x -pthread
. - powinno to działać dla każdego systemu operacyjnego, ponieważ kompilator obsługuje tę funkcję (C++11).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-05 06:20:16
Cóż, technicznie każdy taki obiekt zostanie zbudowany nad biblioteką wątków w stylu C, ponieważ C++ dopiero co określił stock std::thread
model w c++0x, który właśnie został przybity i nie został jeszcze zaimplementowany. Problem jest nieco systemowy, technicznie istniejący model pamięci c++ nie jest wystarczająco ścisły, aby pozwolić na dobrze zdefiniowaną semantykę dla wszystkich przypadków "happens before". Hans Boehm napisał artykuł na ten temat jakiś czas temu i odegrał kluczową rolę w tworzeniu c++0x standard w temacie.
Http://www.hpl.hp.com/techreports/2004/HPL-2004-209.html
To powiedziawszy, istnieje kilka wieloplatformowych bibliotek thread C++, które działają dobrze w praktyce. Intel thread building blocks zawiera obiekt TBB:: thread, który jest zbliżony do standardu c++0x, a Boost ma bibliotekę boost::thread, która to samo.
Http://www.threadingbuildingblocks.org/
Http://www.boost.org/doc/libs/1_37_0/doc/html/thread.html
Używając boost:: thread otrzymałbyś coś w stylu:
#include <boost/thread.hpp>
void task1() {
// do stuff
}
void task2() {
// do stuff
}
int main (int argc, char ** argv) {
using namespace boost;
thread thread_1 = thread(task1);
thread thread_2 = thread(task2);
// do other stuff
thread_2.join();
thread_1.join();
return 0;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-22 06:38:05
Istnieje również biblioteka POSIX dla systemów operacyjnych POSIX. Sprawdź na zgodność
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <iostream>
void *task(void *argument){
char* msg;
msg = (char*)argument;
std::cout<<msg<<std::endl;
}
int main(){
pthread_t thread1, thread2;
int i1,i2;
i1 = pthread_create( &thread1, NULL, task, (void*) "thread 1");
i2 = pthread_create( &thread2, NULL, task, (void*) "thread 2");
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
return 0;
}
Skompiluj z-lpthread
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-02 13:55:21
To w dużej mierze zależy od biblioteki, z której zdecydujesz się korzystać. Na przykład, jeśli używasz biblioteki wxWidgets, utworzenie wątku wyglądałoby tak:
class RThread : public wxThread {
public:
RThread()
: wxThread(wxTHREAD_JOINABLE){
}
private:
RThread(const RThread ©);
public:
void *Entry(void){
//Do...
return 0;
}
};
wxThread *CreateThread() {
//Create thread
wxThread *_hThread = new RThread();
//Start thread
_hThread->Create();
_hThread->Run();
return _hThread;
}
Jeśli główny wątek wywoła metodę CreateThread, utworzysz nowy wątek, który rozpocznie wykonywanie kodu w Twojej metodzie "Entry". W większości przypadków będziesz musiał zachować odniesienie do wątku, aby go dołączyć lub zatrzymać. Więcej informacji tutaj: wxthread documentation
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-06 16:05:10
Oto bardziej rozbudowany sposób tworzenia dowolnej liczby wątków (w C++11 lub nowszym):
#include <thread>
#include <iostream>
using namespace std;
void doSomething(int id) {
cout << "Thread id = " << id;
}
/**
* Spawns n threads
*/
void spawnThreads(int n)
{
thread threads[n];
// spawn n threads:
for (int i = 0; i < n; i++) {
threads[i] = thread(doSomething, i + 1);
}
for (auto& th : threads) {
th.join();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-25 02:58:41
Szukając przykładu klasy C++, która w nowym wątku wywołuje jedną ze swoich własnych metod instancji, pojawia się to pytanie, ale nie byliśmy w stanie użyć żadnej z tych odpowiedzi w ten sposób. Oto przykład, który to robi:
Klasa.hclass DataManager
{
public:
bool hasData;
void getData();
bool dataAvailable();
};
Klasa.cpp
#include "DataManager.h"
void DataManager::getData()
{
// perform background data munging
hasData = true;
// be sure to notify on the main thread
}
bool DataManager::dataAvailable()
{
if (hasData)
{
return true;
}
else
{
std::thread t(&DataManager::getData, this);
t.detach(); // as opposed to .join, which runs on the current thread
}
}
Zauważ, że ten przykład nie wchodzi w mutex lub locking.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-18 18:51:17
Jeśli nie chcemy oddzielnej funkcji w globalnych nazwach, możemy używać funkcji lambda do tworzenia wątków.
Jedną z głównych zalet tworzenia wątków przy użyciu lambda jest to, że nie musimy przekazywać lokalnych parametrów jako listy argumentów. Możemy użyć capture list dla tego samego, a właściwość closure lambda zajmie się cyklem życia.
Oto przykładowy kod
int main() {
int localVariable = 100;
thread th { [=](){
cout<<"The Value of local variable => "<<localVariable<<endl;
}}
th.join();
return 0;
}
Jak na razie uważam, że C++ lambda jest najlepszym sposobem tworzenia wątków szczególnie dla prostsze funkcje wątków
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-08 04:26:49