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.

Author: A-Sharabiani, 2008-11-05

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).
 459
Author: MasterMastic,
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;
}
 74
Author: Edward KMETT,
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

Http://en.wikipedia.org/wiki/POSIX_Threads

 18
Author: Hohenheimsenberg,
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 &copy);

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

 7
Author: LorenzCK,
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();
    }
}
 6
Author: Caner,
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.h
class 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.

 3
Author: livingtech,
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

 3
Author: Daksh,
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