(C ++)线程必须用main()编写吗?

时间:2017-11-18 14:37:44

标签: c++ multithreading timer

背景 所以这是我的问题:我在某个类中有一个方法,它将接受用户输入,直到用户输入“停止信号”,比如“完成”。像:

void getInput(){
    string input;
    cin >> input;
    while (input != "done") {
        cout <<"Please input a word: ";
        linkedlist.push(input);
        cin>> input;
    }
}

现在我必须添加一个计时器来限制这个用户输入一段时间,比如30秒,而链表只会记录用户在30秒内输入的内容,所以我只需要一种方法来打破循环

示例输出:

You have 30 seconds to input the words or input "done" to finish:
Please input a word: pikachu
Please input a word: kapichu
Please input a word: chupika
Please input a word: kachupi
30 seconds has reached. Your inputs are saved.

我刚刚学习了线程,但我注意到每个教程都只在main()中添加了线程,我注意到这篇帖子并尝试了提供的方法,它的工作原理如下:{ {3}}

但是在这里,如果我使用线程来完成我的任务,似乎我需要完全重构我的类或者在main()中逐个运行该类的方法?

问题: 那么,我们可以在正常函数中编写线程并相应地使用它们吗? (衍生问题:如果不是,那么实现它的最佳解决方案是什么?)

我对并发编程很新。请详细说明。谢谢你们!

2 个答案:

答案 0 :(得分:1)

main() 只是一个函数,就像其他函数一样(除了它的名字是保留的,CRT依赖它)。

是的,您可以在&#34;任何地方创建线程&#34; - 是非main()函数,类static或非 - static方法,const或非 - const,内联或不是,public / protected / private,文件本地,lambda等。

答案 1 :(得分:0)

在OSX上,我使用以下内容以超时方式异步获取输入..

#include <chrono>
#include <mutex>
#include <string>
#include <iostream>

#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#else
#include <pthread.h>
#endif

#if defined(_WIN32) || defined(_WIN64)
#define THREAD_RETURN_TYPE DWORD
#else
#define THREAD_RETURN_TYPE void*
#endif

class semaphore
{
private:
    std::mutex mutex;
    std::condition_variable condition;
    uint32_t count = 0;

public:
    void signal()
    {
        std::unique_lock<std::mutex> lock(mutex);
        ++count;
        condition.notify_one();
    }

    void wait()
    {
        std::unique_lock<std::mutex> lock(mutex);
        condition.wait(lock, [&] {
            return count > 0;
        });
        --count;
    }

    bool try_wait()
    {
        std::unique_lock<std::mutex> lock(mutex);
        if (count > 0)
        {
            --count;
            return true;
        }
        return false;
    }

    template<typename Rep, typename Period>
    bool wait_for(const std::chrono::duration<Rep, Period>& relative_time)
    {
        std::unique_lock<std::mutex> lock(mutex);
        bool finished = condition.wait_for(lock, relative_time, [&] {
            return count > 0;
        });

        if (finished)
        {
            --count;
        }
        return finished;
    }

    template<typename Duration>
    bool wait_until(const std::chrono::time_point<std::chrono::high_resolution_clock, Duration>& absolute_time)
    {
        std::unique_lock<std::mutex> lock(mutex);
        bool finished = condition.wait_until(lock, absolute_time, [&] {
            return count > 0;
        });

        if (finished)
        {
            --count;
        }
        return finished;
    }

    template<typename Clock, typename Duration>
    bool wait_until(const std::chrono::time_point<Clock, Duration>& absolute_time)
    {
        return wait_until(std::chrono::high_resolution_clock::now() + (absolute_time - Clock::now()));
    }
};

class simple_thread
{
private:
    #if defined(_WIN32) || defined(_WIN64)
    HANDLE thread;
    #else
    pthread_t thread;
    #endif

public:
    simple_thread(THREAD_RETURN_TYPE (*threadFunc)(void*), void* args)
    {
        #if defined(_WIN32) || defined(_WIN64)
        thread = CreateThread(0, 0, static_cast<LPTHREAD_START_ROUTINE>(threadFunc), args, 0, 0);
        #else
        pthread_create(&thread, nullptr, threadFunc, args);
        #endif
    }

    void join()
    {
        #if defined(_WIN32) || defined(_WIN64)
        WaitForSingleObject(thread, INFINITE);
        #else
        pthread_join(thread, nullptr);
        #endif
    }

    void detach()
    {
        #if defined(_WIN32) || defined(_WIN64)
        CloseHandle(thread);
        #else
        pthread_detach(thread);
        #endif
    }

    void abort()
    {
        #if defined(_WIN32) || defined(_WIN64)
        TerminateThread(thread, 0);
        #else
        pthread_cancel(thread);
        #endif
    }
};





THREAD_RETURN_TYPE getInput(void* args)
{
    std::string* input = static_cast<std::string*>(static_cast<void**>(args)[0]);
    semaphore* sem = static_cast<semaphore*>(static_cast<void**>(args)[1]);

    getline(std::cin, *input);
    sem->signal();
    return 0;
}

int main()
{
    std::string input;
    semaphore sem;
    void* args[2] = {&input, &sem};

    simple_thread thread(getInput, args);

    if (sem.wait_for(std::chrono::seconds(5)))
    {
        std::cout<<"Input";
        thread.join();
    }
    else
    {
        std::cout<<"Invalid Input";
        thread.abort();
    }
}

您也可以使用pthread创建一个带有互斥锁的信号量..或者像上面一样使用c ++ 11 ..

另一件事是我创建了自己的线程类,因为我无法找到杀死std::thread的方法..