Open suxunbin opened 6 years ago
What is the signature of query_thread?
Part of ghttp.cpp
shared_ptr
I could not see anything wrong after a quick look, but making a copy of the response
shared_ptr should work fine. I'll have another look Tomorrow if you have not figured it out by then.
Ah, the problem seems to be that the Res shared_ptr is kept alive too long. The response is sent when the shared_ptr is destructed, and it seems like your Res object is kept alive in a scope higher than the scope of the handler.
Yes,I want to store the Res object in order to use it after the handler. And I find maybe connection between server and client is not broken. But only *response this ostream doesn't send data to the client. So make a copy of the response shared_ptr would lead the ostream confusion?
This is the Response's define in server_http.hpp
In that case, you need to use Response::send to send the data you have added to the response stream to the client. See https://github.com/eidheim/Simple-Web-Server/blob/master/http_examples.cpp#L183 for an example.
This is the server_http.hpp that I used. *response will send the data to the client itself,will it?
Sadly that would be too inefficient. The data is sent when Response::send is called, or when the Response object within the shared_ptr is destroyed.
Actually,I'm writing a threadpool.
pool.create() create a daemon thread to continuously get task from tasklines and run query_thread().
Where, tasklines is a global variable
However, I find that if I don't sleep(10) in query_handler(), the daemon thread will not get response and request object.
In other words, if I leave query_handler() scope, the daemon thread(detached from the server) will not get response and request object.
When I am in query_handler() scope,obviously the response and request object are valid wherever they are referred(for example, Task , tasklines, the daemon thread). However, when I leave query_handler() scope, the response and request object are invalid wherever they are referred. And I want the response and request object to be kept alive in a scope higher than the scope of the handler.(for example , the location of pool.create() )
Can I have a way that when I leave the scope,the response and request object are still alive?
I hope that server.resource doesn't destroy the response and request object when they leave the scope.
I have read the https://github.com/eidheim/Simple-Web-Server/blob/master/http_examples.cpp#L183 example.
My purpose is to use referrence of the response and request object on the location in the picture.
In other words, I hope to store referrence of the response and request object as global variables in order that other threads can use them.
The purpose of shared_ptr's is typically to extend the lifetime of an object. When you pass the shared_ptr to query_thread, the shared_ptr is copied and thus the object's lifetime is extended. You should in general not need to store shared_ptr's globally.
However, I need thread scheduling. So I only store them in query_handler(). Another thread is responsible for query_thread(). I can't directly pass the shared_ptr to query_thread() in query_handler(). I need another thread to know all the shared_ptrs in order to assign.
For example,if there are 60 queries but I only have 30 threads in the threadpool. If I directly pass the shared_ptr to query_thread().Then there are 30 shared_ptr that can't pass.I must store them. So how should I store the rest shared_ptr so that they are still valid when they leave the scope.
Regarding a thread pool of size 30, here is a simplified example of how I would implement this using asio:
#include "server_http.hpp"
class Workers {
public:
boost::asio::io_service service;
private:
boost::asio::io_service::work work;
std::vector<std::thread> threads;
public:
Workers(size_t number_of_threads) : work(service) {
for(size_t c = 0; c < number_of_threads; ++c) {
threads.emplace_back([this] {
service.run();
});
}
}
};
using namespace std;
using HttpServer = SimpleWeb::Server<SimpleWeb::HTTP>;
int main() {
Workers workers(30);
HttpServer server;
server.config.port = 8080;
server.default_resource["GET"] = [&workers](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> /*request*/) {
workers.service.post([response] {
this_thread::sleep_for(chrono::seconds(5)); // Simulate time-consuming work
response->write("Work done");
});
};
server.start();
}
The response-shared_ptr is here copied by capture in workers.service.post
and thus kept alive throughout the handler.
In this way,if 30 threads are running,then what about the new shared_ptr ?
If use workers.service.post, how should I sort these handlers in io_service. I could not handle thest tasks according to the order of their entry.
I use the example you give me. But client gets nothing.
If I don't use workers.service.post(), client can directly get the data.
So, when I leave this scope, the response shared_ptr becomes invalid.
I find a problem when I use server_http.hpp(old version) in http.
"response" is a shared_ptr type. In this way, response can send data to the client.
However,
When I let "Res" equal to "response",response can not send data to the client.
Why I can't pass a shared_ptr to another.