mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-14 17:00:52 +08:00
222 lines
5.4 KiB
C
222 lines
5.4 KiB
C
#include "lib_acl.h"
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <assert.h>
|
||
|
||
typedef struct {
|
||
ACL_SOCKET fd;
|
||
int i;
|
||
} IPC_CTX;
|
||
|
||
typedef struct {
|
||
ACL_AIO *aio;
|
||
ACL_MSGIO *mio;
|
||
ACL_VSTREAM *stream;
|
||
int n;
|
||
int stop;
|
||
acl_pthread_t tid;
|
||
} IPC;
|
||
|
||
typedef struct {
|
||
IPC *ipc;
|
||
|
||
ACL_MSGIO *local_mio;
|
||
ACL_VSTREAM *local_stream;
|
||
} IPC_CLIENT;
|
||
|
||
#define MSG_IPC_ACCEPT 100
|
||
#define MSG_IPC_STOP 101
|
||
|
||
#if 0
|
||
#define USE_IPC_SYNC
|
||
#endif
|
||
|
||
static ACL_MSGIO *__ipc_listener = NULL;
|
||
static IPC_CLIENT *__ipc_clients = NULL;
|
||
static ACL_AIO *__aio_listener = NULL;
|
||
static char __ipc_addr[256];
|
||
|
||
static int msg_ipc_stop(int msg_type acl_unused, ACL_MSGIO *mio acl_unused,
|
||
const ACL_MSGIO_INFO *info acl_unused, void *arg)
|
||
{
|
||
IPC *ipc = (IPC*) arg;
|
||
ipc->stop = 1;
|
||
printf("close now(%s)\n", acl_last_serror());
|
||
return (0);
|
||
}
|
||
|
||
static int msg_ipc_accept(int msg_type acl_unused, ACL_MSGIO *mio acl_unused,
|
||
const ACL_MSGIO_INFO *info, void *arg)
|
||
{
|
||
IPC *ipc = (IPC*) arg;
|
||
IPC_CTX ctx;
|
||
|
||
memcpy(&ctx, acl_vstring_str(info->body.buf), ACL_VSTRING_LEN(info->body.buf));
|
||
if (ipc->n % 10000 == 0)
|
||
printf("tid: %ld, fd: %d\n", (long) acl_pthread_self(), ctx.fd);
|
||
ipc->n++;
|
||
return (0);
|
||
}
|
||
|
||
#ifdef USE_IPC_SYNC
|
||
static int service_sync_loop_read(ACL_MSGIO *mio)
|
||
{
|
||
ACL_VSTREAM *vstream = acl_msgio_vstream(mio);
|
||
int i = 0;
|
||
|
||
acl_non_blocking(ACL_VSTREAM_SOCK(vstream), ACL_BLOCKING);
|
||
|
||
while (1) {
|
||
char buf[256];
|
||
int ret = acl_vstream_read(vstream, buf, sizeof(buf));
|
||
if (ret == ACL_VSTREAM_EOF) {
|
||
printf("tid: %ld, read error(%s)\n",
|
||
acl_pthread_self(), acl_last_serror());
|
||
return (0);
|
||
}
|
||
if (0 && i++ % 10000 == 0)
|
||
printf("tid: %ld, i: %d\n", acl_pthread_self(), i);
|
||
}
|
||
|
||
return (i);
|
||
}
|
||
#endif
|
||
|
||
static void *service_thread(void *arg)
|
||
{
|
||
IPC *ipc = (IPC*) arg;
|
||
ACL_MSGIO *mio = ipc->mio;
|
||
ACL_AIO *aio = acl_msgio_aio(mio);
|
||
|
||
acl_tcp_set_rcvbuf(ACL_VSTREAM_SOCK(acl_msgio_vstream(mio)), 1024000);
|
||
|
||
#ifdef USE_IPC_SYNC
|
||
service_sync_loop_read(mio);
|
||
return (NULL);
|
||
#endif
|
||
|
||
/* <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>ѭ<EFBFBD><D1AD> */
|
||
while (1) {
|
||
acl_aio_loop(aio);
|
||
if (ipc->stop) {
|
||
printf("tid: %ld, stop now, n: %d\n",
|
||
(long) acl_pthread_self(), ipc->n);
|
||
break;
|
||
}
|
||
}
|
||
|
||
return (NULL);
|
||
}
|
||
|
||
static void init(int nthread)
|
||
{
|
||
acl_pthread_attr_t attr;
|
||
int i;
|
||
|
||
acl_init();
|
||
|
||
__ipc_clients = (IPC_CLIENT*) acl_mycalloc(nthread, sizeof(IPC_CLIENT));
|
||
|
||
acl_pthread_attr_init(&attr);
|
||
acl_pthread_attr_setdetachstate(&attr, 0);
|
||
|
||
__aio_listener = acl_aio_create(ACL_EVENT_SELECT);
|
||
__ipc_listener = acl_msgio_listen(__aio_listener, NULL);
|
||
assert(__ipc_listener);
|
||
acl_msgio_addr(__ipc_listener, __ipc_addr, sizeof(__ipc_addr));
|
||
printf("listening on: %s\n", __ipc_addr);
|
||
|
||
for (i = 0; i < nthread; i++) {
|
||
__ipc_clients[i].ipc = (IPC*) acl_mycalloc(1, sizeof(IPC));
|
||
__ipc_clients[i].ipc->aio = acl_aio_create(ACL_EVENT_SELECT);
|
||
__ipc_clients[i].ipc->mio = acl_msgio_connect(__ipc_clients[i].ipc->aio, __ipc_addr, 0);
|
||
/*
|
||
acl_msgio_set_noblock(__ipc_clients[i].ipc->aio, __ipc_clients[i].ipc->mio);
|
||
*/
|
||
acl_msgio_reg(__ipc_clients[i].ipc->mio, MSG_IPC_ACCEPT,
|
||
msg_ipc_accept, __ipc_clients[i].ipc);
|
||
acl_msgio_reg(__ipc_clients[i].ipc->mio, MSG_IPC_STOP,
|
||
msg_ipc_stop, __ipc_clients[i].ipc);
|
||
acl_msgio_reg(__ipc_clients[i].ipc->mio, ACL_MSGIO_EXCEPT,
|
||
msg_ipc_stop, __ipc_clients[i].ipc);
|
||
|
||
acl_pthread_create(&__ipc_clients[i].ipc->tid, &attr, service_thread, __ipc_clients[i].ipc);
|
||
__ipc_clients[i].local_mio = acl_msgio_accept(__ipc_listener);
|
||
assert(__ipc_clients[i].local_mio);
|
||
__ipc_clients[i].local_stream = acl_msgio_vstream(__ipc_clients[i].local_mio);
|
||
acl_non_blocking(ACL_VSTREAM_SOCK(__ipc_clients[i].local_stream), ACL_NON_BLOCKING);
|
||
acl_tcp_set_sndbuf(ACL_VSTREAM_SOCK(__ipc_clients[i].local_stream), 1024000);
|
||
acl_tcp_set_nodelay(ACL_VSTREAM_SOCK(__ipc_clients[i].local_stream));
|
||
}
|
||
}
|
||
|
||
static void run(int nthread, int nloop)
|
||
{
|
||
int i, ret;
|
||
IPC_CTX ctx;
|
||
time_t begin = time(NULL);
|
||
|
||
for (i = 0; i < nloop; i++) {
|
||
memset(&ctx, 0, sizeof(ctx));
|
||
ctx.fd = i;
|
||
#ifdef USE_IPC_SYNC
|
||
acl_vstream_write(__ipc_clients[i % nthread].local_stream, &ctx, sizeof(IPC_CTX));
|
||
#else
|
||
ret = acl_msgio_send(__ipc_clients[i % nthread].local_mio, MSG_IPC_ACCEPT, &ctx, sizeof(IPC_CTX));
|
||
if (ret < 0)
|
||
break;
|
||
#endif
|
||
if (i % 10000 == 0)
|
||
printf("run(tid=%ld): i=%d\n", (long) acl_pthread_self(), i);
|
||
}
|
||
|
||
for (i = 0; i < nthread; i++) {
|
||
memset(&ctx, 0, sizeof(ctx));
|
||
ctx.fd = -1;
|
||
acl_msgio_send(__ipc_clients[i].local_mio, MSG_IPC_STOP, &ctx, sizeof(IPC_CTX));
|
||
}
|
||
for (i = 0; i < nthread; i++)
|
||
acl_pthread_join(__ipc_clients[i].ipc->tid, NULL);
|
||
for (i = 0; i < nthread; i++)
|
||
acl_msgio_close(__ipc_clients[i].local_mio);
|
||
acl_myfree(__ipc_clients);
|
||
printf(">>>time cost: %ld\n", time(NULL) - begin);
|
||
}
|
||
|
||
static void usage(const char *procname)
|
||
{
|
||
printf("usage: %s -h [help] -c nthreads -n nloop\n", procname);
|
||
}
|
||
|
||
int main(int argc, char *argv[])
|
||
{
|
||
int nthread = 2, nloop = 1000000, ch;
|
||
|
||
acl_msg_stdout_enable(1);
|
||
|
||
while ((ch = getopt(argc, argv, "hc:n:")) > 0) {
|
||
switch (ch) {
|
||
case 'h':
|
||
usage(argv[0]);
|
||
return (0);
|
||
case 'n':
|
||
nloop = atoi(optarg);
|
||
break;
|
||
case 'c':
|
||
nthread = atoi(optarg);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (nthread <= 0)
|
||
nthread = 2;
|
||
if (nloop <= 0)
|
||
nloop = 1000;
|
||
|
||
init(nthread);
|
||
run(nthread, nloop);
|
||
return (0);
|
||
}
|