线程的执行体为了便于观察我修改了一下
#include <ace/Thread_Manager.h>
#include <ace/INET_Addr.h>
#include <ace/SOCK_Acceptor.h>
#include <ace/SOCK_Stream.h>
#include <ace/Guard_T.h>
#include <ace/Thread_Mutex.h>
#include <iostream>
using namespace std;
#define LOG_RECORD_MAX 100
// At file scope.
// Keep track of number of logging requests.
static int request_count;
// Manage threads in this process.
static ACE_Thread_Manager thr_mgr;
// Lock to protect request_count.
static ACE_Thread_Mutex lock;
ACE_THR_FUNC_RETURN logging_handlerd(void *arg);
// Forward declaration.
static ACE_THR_FUNC logging_handler=logging_handlerd;
//static int (*logging_handler)(void *);
// Port number to listen on for requests.
static const int logging_port = 10000;
// Main driver function for the multi-threaded
// logging server. Some error handling has been
// omitted to save space in the example.
int main (int argc, char *argv[])
{
// Internet address of server.
ACE_INET_Addr addr (logging_port);
// Passive-mode acceptor object.
ACE_SOCK_Acceptor server(addr);
ACE_SOCK_Stream new_stream;
// Wait for a connection from a client.
for (;;)
{
// Accept a connection from a client.
server.accept (new_stream);
// Get the underlying handle.
ACE_HANDLE h = new_stream.get_handle ();
// Spawn off a thread-per-connection.
thr_mgr.spawn (logging_handler,
reinterpret_cast <void *> (h),
THR_DETACHED);
}
}
// Entry point that processes logging records for
// one client connection.
ACE_THR_FUNC_RETURN logging_handlerd(void *arg)
{
cout<<"a new connection from a client";
ACE_HANDLE h = reinterpret_cast <ACE_HANDLE> (arg);
// Create a <SOCK_Stream> object from SOCKET <h>.
ACE_SOCK_Stream stream (h);
for (;;)
{
int len;// Ensure a 32-bit quantity.
char log_record[LOG_RECORD_MAX];
// The first <recv_n> reads the length
// (stored as a 32-bit integer) of
// adjacent logging record. This code
// handles "short-<recv>s".
/*ssize_t n = stream.recv_n
(reinterpret_cast <char *> (&len),
sizeof len);*/
for (int r_bytes = 0;;)
{
r_bytes =stream.recv (log_record, sizeof log_record);
if (r_bytes > 0)
write (1, log_record, r_bytes);
else
break;
}
// Bail out if we’re shutdown or
// errors occur unexpectedly.
//if (n <= 0) break;
//len = ntohl (len); // Convert byte-ordering.
//if (len > LOG_RECORD_MAX) break;
// The second <recv_n> then reads <len>
// bytes to obtain the actual record.
// This code handles "short-<recv>s".
//n = stream.recv_n (log_record, len);
// Bail out if we’re shutdown or
// errors occur unexpectedly.
/*if (n <= 0) break;
cout<<log_record;*/
//{
// // Constructor of Guard automatically
// // acquires the lock.
// ACE_Guard<ACE_Thread_Mutex> mon (lock);
// // Execute following two statements in a
// // critical section to avoid race conditions
// // and scrambled output, respectively.
// ++request_count; // Count # of requests
// if (write (n, log_record, len) == -1)
// break;
// // Destructor of Guard automatically
// // releases the lock, regardless of
// // how we exit this block!
//}
}
// Destructor of <stream> automatically
// closes down <h>.
return 0;
}