Juanti
Juanti

Reputation: 75

Killing thread from another thread c++

I am new to multithreading and i need your help. Consider the following code:

vector <int> vec; 
int j = 0;
void Fill()
{
    for (int i = 0; i < 500; i++)
    {
        Sleep(500);
        vec.push_back(i);
    }

}


void Proces()
{
    int count = 0;
    int n=-1;
    while (true) {
        Sleep(250);
        if (!vec.empty())
        {
            if (n != vec.back()) {
                n = vec.back();
                cout << n;
                count++;
            }
        }
        if (count == 101)break;
    }
}

void getinput()
{
    while (true) {
        int k=0;
        cin >> k;

            //if the user enters an integer i want to kill all the threads
    }
}
int main()
{
    thread t1(Fill);
    thread t2(Proces);
    thread t3(getinput);
    t1.join();
    t2.join();
    t3.join();
    cout << "From main()";


}

The point is that i want to kill t1(Fill) and t2(Proces) from t3(getinput).Is there and way to do it,and if there is could you please post and example.

Upvotes: 2

Views: 9606

Answers (3)

Some programmer dude
Some programmer dude

Reputation: 409432

A common way to make a thread exit is to have an (atomic) flag that the thread checks to see if it should exit. Then externally you set this flag and the thread will notice it and exit naturally.

Something like

#include <thread>
#include <atomic>
#include <iostream>
#include <chrono>

// Flag telling the thread to continue or exit
std::atomic<bool> exit_thread_flag{false};

void thread_function()
{
    // Loop while flag if not set
    while (!exit_thread_flag)
    {
        std::cout << "Hello from thread\n";
        std::this_thread::sleep_for(std::chrono::seconds(1));  // Sleep for one second
    }
}

int main()
{
    std::thread t{thread_function};  // Create and start the thread
    std::this_thread::sleep_for(std::chrono::seconds(5));  // Sleep for five seconds
    exit_thread_flag = true;  // Tell thread to exit
    t.join();  // Wait for thread to exit
}

Upvotes: 3

Blacktempel
Blacktempel

Reputation: 3995

You have to define an exit condition and lock the container before accessing it. Of course you could build an own collection as wrapper around an existing using proper locking and thus making it thread-safe.

Here is an example of locking and an exit condition:

class Test
{
public:
    Test()
        : exitCondition(false)
    {
        work = std::thread([this]() { DoWork(); });
    }

    ~Test()
    {
        if (work.joinable())
            work.join();
    }

    void Add(int i)
    {
        mutex.lock();
        things.push_back(i);
        mutex.unlock();
    }

    void RequestStop(bool waitForExit = false)
    {
        exitCondition.exchange(true);
        if (waitForExit)
            work.join();
    }

private:
    void DoWork()
    {
        while (!exitCondition)
        {
            mutex.lock();
            if (!things.empty())
            {
                for (auto itr = things.begin(); itr != things.end();)
                    itr = things.erase(itr);
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
            mutex.unlock();
        }
    }

private:
    std::vector<int> things;

    std::thread work;
    std::atomic<bool> exitCondition;
    std::mutex mutex;
};

int wmain(int, wchar_t**)
{
    Test t;
    t.Add(1);
    t.Add(2);
    t.Add(3);

    t.RequestStop(true);

    return 0;
}

Upvotes: 2

Daniel Langr
Daniel Langr

Reputation: 23527

std::atomic<bool> exit_flag{false};
...
void Fill() {
   for (int i = 0; i < 500; i++) {
      if (exit_flag) return;
      ...
   }
}

void Proces() {
   while (true) {
      if (exit_flag) return;
      ...
   }
}

void getinput() {
   while (true) {
      ...
      if ( /* the user enters an integer i want to kill all the threads */ )
         exit_flag = true;
   }
}

Upvotes: 0

Related Questions