(C++)是否必须在main()中编写线程
(C++) Is a thread must be written in main()?
背景:所以我的问题是:我在某个类中有一个方法,它会接受用户输入,直到用户输入"停止信号",比如"完成"。类似:
void getInput(){
string input;
cin >> input;
while (input != "done") {
cout <<"Please input a word: ";
linkedlist.push(input);
cin>> input;
}
}
现在我必须添加一个计时器来限制用户输入一定的时间,比如30秒,而linkedlist只会记录用户在这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.
我刚刚学习了thread,但我注意到每个教程都只将线程放在main()中,我注意到了这篇文章,并尝试了提供的方法,它在实际情况下有效:如何在C++中使用计时器在给定时间内强制输入?。
但在这里,如果我要使用线程来实现我的任务,似乎我需要完全重组我的类,或者在main()中逐个运行该类的方法?
问题:那么,我们可以在正常函数中编写线程并相应地使用它们吗?(衍生问题:如果没有,实现它的最佳解决方案是什么?)
我对并发编程很陌生。请详细说明。谢谢大家!
main()
只是一个函数,与其他函数非常相似(只是它的名称是保留的,CRT依赖于它)。
是的,您可以从"任何位置"创建线程,无论是非main()
函数、类的static
或非static
方法、const
或非const
、内联或非内联、public
/protected
/private
、文件本地、lambda
等。
在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
的方法。。
相关文章:
- 在main()之外初始化std::vector会导致性能下降(多线程)
- main() 对连续运行的线程中的编辑值具有只读访问权限 - C++
- GLFW & ImGui:从 main 以外的线程创建 ImGui 控件
- 尝试在dll main中创建线程
- C++ - 在 main() 方法内的类实例中创建一个线程并调用 Sleep()
- 如何使 WaitForSingleObject 在从 main 调用的线程内接收信号作为类成员函数
- (C++)是否必须在main()中编写线程
- 线程中的异常 "main" java.lang.UnsatisfiedLinkError: no JNTIest in java.library.path
- QT 5.7对于Android Main C 线程不持续运行
- 可以(通过编译器)使用多少个线程来初始化全局对象(函数main之前)
- 是否允许主线程在进入main()之前生成POSIX线程
- C++ 中"main"线程的 ID
- 线程"main" java.lang.UnsatisfiedLinkError: Native.initiate(I)V 从 Java 运行本机 dll 时
- main()和线程()之间的通信
- main 终止具有无限循环的线程
- 从对象成员函数在 main 中生成线程
- Java:调用本机方法,给出"线程"main"java.lang.UnsatisfiedLinkError中的异常"
- 线程"main" java.lang.UnsatisfiedLinkError: java.library.path 中没有libopencv_java247
- 线程"main" java.lang.UnsatisfiedLinkError 中的异常
- 线程"main" java.lang.UnsatisfiedLinkError: undefined symbol: test