我正在使用boost库来实现套接字通信.对于我的主应用程序,应启动一个处理所有传入请求的连接处理程序.
因此,我将整个服务器处理程序封装到类服务器中.创建服务器对象时,它应该启动服务器.
但是这样线程就会与构造函数代码的执行结束一起死掉.我想我不知道boost/posix线程是如何工作的.我来自Java背景.
server::server(int port) {
try {
boost::asio::io_service io_service;
tcp_server server(io_service, port);
boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
} catch (std::exception& e) {
std::cerr << e.what() << std::endl;
}
Run Code Online (Sandbox Code Playgroud) 我使用以下方法构建了boost:
bjam --toolset=gcc --with-thread stage
Run Code Online (Sandbox Code Playgroud)
每当我试图实际使用Boost.Thread时我会得到未定义的引用,尽管我链接它.其他Boost库(如Regex或System)不会发生这种情况.
>g++ main.cpp -I. -L. -lboost_thread-mgw45-mt-1_46_1
C:\Users\jhasse\AppData\Local\Temp\ccjYfDox.o:main.cpp:(.text+0xf): undefined reference to `_imp___ZN5boost6thread20hardware_concurrencyEv'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
示例程序:
#include <boost/thread.hpp>
#include <iostream>
int main()
{
std::cout << boost::thread::hardware_concurrency() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
我试图防止线程在特定范围内时中断.但是,使用boost::this_thread::disable_interruption di()似乎没有任何影响.
#include <boost/thread.hpp>
#include <iostream>
void worker() {
std::cout << "START" << std::endl;
for(;;) {
{
boost::this_thread::disable_interruption di();
try {
boost::this_thread::sleep(boost::posix_time::seconds(1));
}
catch(boost::thread_interrupted & e) {
assert( false );
}
}
try {
boost::this_thread::interruption_point();
}
catch(boost::thread_interrupted & e) {
break;
}
}
std::cout << "END" << std::endl;
}
int main() {
boost::thread thread(&worker);
thread.interrupt();
thread.join();
}
Run Code Online (Sandbox Code Playgroud)
文档似乎暗示boost::this_thread::sleep()不会抛出boost::thread_interrupted,而di在范围内.
我究竟做错了什么?
使用MS Visual C++ 2012
类具有类型的成员 std::atomic_flag
class A {
public:
...
std::atomic_flag lockFlag;
A () { std::atomic_flag_clear (&lockFlag); }
};
Run Code Online (Sandbox Code Playgroud)
有一个类型A的对象
A object;
Run Code Online (Sandbox Code Playgroud)
谁可以被两个(Boost)线程访问
void thr1(A* objPtr) { ... }
void thr2(A* objPtr) { ... }
Run Code Online (Sandbox Code Playgroud)
如果另一个线程正在访问该对象,则该想法是等待该线程.
问题是:是否有可能用atomic_flag对象构造这样的机制?不是说暂时,我想要一些轻量级的boost :: mutex.
顺便说一下,其中一个线程涉及的进程是一个非常长的查询到获得很多行的dBase,我只需要在发生冲突的某个代码区域中挂起它(当处理每一行时)我不能等待整个线程完成join().
我在每个帖子中试过一些:
thr1 (A* objPtr) {
...
while (std::atomic_flag_test_and_set_explicit (&objPtr->lockFlag, std::memory_order_acquire)) {
boost::this_thread::sleep(boost::posix_time::millisec(100));
}
... /* Zone to portect */
std::atomic_flag_clear_explicit (&objPtr->lockFlag, std::memory_order_release);
... /* the process continues */
}
Run Code Online (Sandbox Code Playgroud)
但没有成功,因为第二个线程挂起.实际上,我并不完全理解该atomic_flag_test_and_set_explicit函数所涉及的机制.如果这样的函数不能立即返回,或者可以延迟直到可以锁定标志.
对我来说,如何获得一个具有这样一个函数的锁定机制并始终设置该值并返回之前的值也是一种谜.没有选项只能读取实际设置.
欢迎任何建议.
我正在尝试使用C++中的线程和互斥体进行简单的操作.
这是代码:
#include <iostream>
#include <boost/thread/thread.hpp>
class mutex_test
{
private:
boost::mutex mut;
public:
void operator()()
{
boost::mutex::scoped_lock lock(mut);
std::cout << "Hi!" << std::endl;
}
};
int main()
{
mutex_test tester;
boost::thread tester_thread(tester);
tester_thread.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在编译时,我收到此错误:
In file included from C:\boost/boost/thread/detail/thread.hpp:15:0,
from C:\boost/boost/thread/thread.hpp:22,
from main.cpp:3:
C:\boost/boost/thread/detail/move.hpp: In instantiation of 'typename boost::decay<T>::type boost::thread_detail::decay_copy(T&&) [with T = mutex_test&; typename boost::decay<T>::type = mutex_test]':
C:\boost/boost/thread/detail/thread.hpp:265:88: required from 'boost::thread::thread(F&&) [with F = mutex_test&]'
main.cpp:20:36: required from here
C:\boost/boost/thread/detail/move.hpp:246:37: error: use of deleted function 'mutex_test::mutex_test(const …Run Code Online (Sandbox Code Playgroud) boost库(在C++ 11标准之前)提供了对线程的支持.作为其支持的一部分,它还提供了"障碍"的实现,这是一个允许同步的简单类.引用boost网站:
"屏障是一个简单的概念.也称为集合点,它是多个线程之间的同步点.屏障配置为特定数量的线程(n),当线程到达屏障时,它们必须等到所有n个线程一旦第n个线程到达屏障,所有等待的线程都可以继续,并且屏障被重置."
屏障(等待)的主要功能的实现,如Boost 1.54,如下所示:
bool wait()
{
boost::mutex::scoped_lock lock(m_mutex);
unsigned int gen = m_generation;
if (--m_count == 0)
{
m_generation++;
m_count = m_threshold;
m_cond.notify_all();
return true;
}
while (gen == m_generation)
m_cond.wait(lock);
return false;
}
Run Code Online (Sandbox Code Playgroud)
可以看出,屏障是可重复使用的:一旦建成,它在首次使用后不需要被销毁.
我现在的问题是:变量m_generation是什么?我假设boost库的编写者有理由将其包含在内.每次屏障重置/准备重复使用时它会递增,但到底是什么?它是一个私有变量,因此无法从外部读出.使用wait()函数中的简单内部bool变量可以很容易地解决同样的问题,而不需要私有类变量.
我有一个线程(升压::线程)的正确使用的问题
我想有X线程在同一时间,像这样运行相同的功能
while( true )
server.run();
Run Code Online (Sandbox Code Playgroud)
这是我目前编程的方式,这是运行功能
void server::run()
{
std::vector<boost::thread*> threads;
for(std::size_t i = 0; i < threadPool; ++i)
{
threads.push_back( new boost::thread( boost::bind(&seed::server::pollEvent,this) ) );
}
for( auto & x : threads )
x->join();
for( auto & x : threads )
x->detach();
for( auto & x : threads )
delete x;
}
Run Code Online (Sandbox Code Playgroud)
但是,这种不断用起来比较多的RAM,在开始大约20MB的和去成无限大,我的问题是,什么是这个正确的方法呢?
使用SFML的线程时不会发生此问题.(CPU使用率略高,但不会占用每个线程的ram,它们被正确清除)
我有一个队列类,其数据存储在向量中:
std::vector<boost::shared_ptr<rxImage> > queue;
Run Code Online (Sandbox Code Playgroud)
有一个线程添加到基于此循环的队列:
while(runRxThread){
this->rxImage();
}
Run Code Online (Sandbox Code Playgroud)
其中rxImage()的定义如下:
zmq::message_t img;
imageSocket->recv(&img);
//addToQueue is a push back:
//queue.push_back( boost::shared_ptr<rxImage> (new rxImage(data, imgSize)) );
localQueue->addToQueue((unsigned char*) img.data());
Run Code Online (Sandbox Code Playgroud)
这个图像在这个帖子中得到了很好的接收(我已经测试了10,000左右,看起来很好).
runRxThread变量是通过定义线程函数的类中的一些setter函数设置的.
当我在主线程中运行一个进程时,例如:
startRx(); //start the thread
/*process to stimulate the sending of network data from another program*/
stopRX(); //stop the thread from accessing the queue
queue.clear();
Run Code Online (Sandbox Code Playgroud)
由clear()引起的段错误.我已经检查过它肯定是这条线而不是对象的内部管道,它绝对是.
它似乎是一个线程安全问题,但我不知道如何解决它,更重要的是,我不知道为什么.我的理解是两个线程可以写入同一个内存,但不能同时写入.当然,通过设置我的runRxThread变量,我确保不会发生这种情况.
我非常想要一个不涉及互斥锁或信号量的解决方案 - 我真的不认为它们对于像这样的问题是必要的.
谢谢!
编辑:runRXThread是volatile并且线程循环现在是:
while(1){
if(runRxThread == 1){
this->rxImage();
}
}
Run Code Online (Sandbox Code Playgroud)
EDIT2:"在共享对象上使用互斥锁"
好吧,这显然是一个线程安全问题,我需要让我的共享变量线程安全.但...
1)rxImage(); 除非有数据发送,否则不会终止
2)段错误发生在rxImage()中;
3)如果我用互斥锁锁定队列,那么程序肯定会在rxImage中挂起,直到有数据,因为互斥锁不会被释放
4)没有数据发送,所以程序将永远挂起.
我的理解不正确吗?
EDIT3:
我已将rxImage()更改为非阻塞:
zmq::message_t img;
imageSocket->recv(&img,ZMQ_NOBLOCK); …Run Code Online (Sandbox Code Playgroud) 我有一个Python应用程序调用C++ boost python库,它都可以工作.但是,我有一个回调C++到Python的场景,其中来自boost线程的C++调用python,我在C++端获得访问冲突.如果我使用python线程执行完全相同的回调,它可以完美地工作.因此我怀疑我不能简单地使用boost线程从C++回调Python,但需要做一些额外的工作吗?
boost-thread ×10
c++ ×10
boost ×8
atomicity ×1
barrier ×1
boost-asio ×1
boost-mutex ×1
boost-python ×1
c++11 ×1
functor ×1
mingw ×1
python ×1