
Hi all, I am using 1_39_0 version boost in my application, and encounter two problems, one with tcp::socket and another with thread. The following is my codes: class transStream { public: transStream() { cb = NULL; thrd = NULL; } ~transStream() { if (sock) { sock->close; // would be segment fault delete sock; // would be segment fault } if (thrd) { cout << "ready to delete the thread ..." << endl; //delete thrd; thrd->interrupt(); // actually, the thread still exists and runs thrd->detach(); cout << "detach the thread ..." << endl; thrd = NULL; } cb = NULL; cout << "finish..." << endl; } tcp::socket* sock; TransDataCallBack cb; boost::thread* thrd; }; static void getDataThread(transStream* ts) { if (!ts) { return ; } cout << "in getDataThread method ...." << endl; try { boost::system::error_code error; char packet[PACKET_LENGTH] = {0}; memset(packet, 0, PACKET_LENGTH); for (;;) { ... usleep(10); } cout << " exit the for loop " << endl; } catch(std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } if (ts) delete ts; return ; } int CreateTransStream(OUT void** pTsHandle, IN const char* sTransIp, IN unsigned short servTransPort, IN const CONVERT_STREAM_INFO* pInfo) { if (!sTransIp || !pInfo) { cout << "error parameters" << endl; return -1; } stringstream ss; string port; transStream* ts = new transStream(); ... ts->sock = sock; *pTsHandle = ts; cout << "finish sending the dahua device info to server and return ..." << endl; return 0; } int StartTransStream(IN void* tsHandle, IN TransDataCallBack cb, IN void* userData) { stringstream ss; transStream* ts = (transStream*)tsHandle; if (!tsHandle || !ts) { return -1; } ... ts->cb = cb; boost::thread* thrd = new boost::thread(boost::bind(getDataThread, ts)); ts->thrd = thrd; ... return 0; } int StopTransStream(IN void* tsHandle) { transStream* ts = (transStream*)tsHandle; if (!tsHandle || !ts) { return -1; } ... return 0; } int DestroyTransStream(IN void* tsHandle) { transStream* ts = (transStream*)tsHandle; if (!tsHandle || !ts) { return -1; } cout << "in method DestroyTransStream ..." << endl; if (ts->thrd) { cout << "destory the thread ..." << endl; if (ts) { delete ts; cout << "reset ..." << endl; ts = NULL; } } cout << "deleted the socket ..." << endl; return 0; } 1. the first problem: in the function CreateTransStream, i declare a transStream using "transStream* ts = new transStream();" and a socket using "tcp::socket* sock = new tcp::socket(io_service);", "ts->sock = sock;" , then i return the ts using "*pTsHandle = ts;" ; When i delete the ts in the function DestroyTransStream: "delete ts;", i know the system would call the deconstruct function ~transStream(), when i call sock->close() or delete sock, Segment Fault will occurs. Can somebody tell me why? Or how can i solve the problem? 2. the second problem: If i want to kill a thread which is no longer useful, I think i just need to call the two lines: " thrd->interrupt();" and " thrd->detach();" . But actully, the two lines cannot kill the thread. Can somebody tell me how to do? Thinks in advances!

xutm wrote:
class transStream { public: transStream() { cb = NULL; thrd = NULL; } ~transStream() { if (sock) {
The value of sock is undefined here, which might explain some problems you're having.
sock->close; // would be segment fault
Did you mean sock->close()?
if (thrd) { cout << "ready to delete the thread ..." << endl; //delete thrd; thrd->interrupt(); // actually, the thread still exists and runs
That's normal. You can't just stop threads, you can only request that it stops. The thread will be stopped when the next interruption point is reached. See the documentation about what interruption points are.

xutm wrote:
If i want to kill a thread which is no longer useful, I think i just need to call the two lines: " thrd->interrupt();" and " thrd->detach();" . But actully, the two lines cannot kill the thread.
POSIX defines a thread cancellation scheme in which a thread that is blocked doing i/o can be killed, however nether Boost.Thread nor the forthcoming C++0x std::thread allow this. If you are running on a POSIX platform you can avoid those C++ thread libraries and manage threads directly via the POSIX API, but in that case you have the question of how cleanly the killed thread will terminate i.e. will it call destructors. In general it will not do so, but GNU libc does call destructors in this case. So you can get the behaviour that you want if you are running on a GNU libc platform and if you're prepared to write your own thread class. Otherwise, threads that are blocking doing i/o are unkillable. One work-around is to have a single thread doing all i/o using e.g. select() to avoid blocking, and transfering data to and from the other threads using condition variables. Those threads will block waiting on the condition variables, and that blocking is interruptable with Boost.Thread. (I don't know much about Boost.asio, but I would guess that it has support for this sort of thing.) Or, just don't use threads. Regards, Phil.
participants (3)
-
Mathias Gaunard
-
Phil Endecott
-
xutm