mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-11-29 18:37:41 +08:00
优化了线程池的性能
通过给线程池中的每一个线程一个独立的线程条件变量(之前是用同一个),大大减少了线程池在任务调度时的竞争问题
This commit is contained in:
parent
99f2645bda
commit
a3b2e1f6d1
@ -1,6 +1,11 @@
|
||||
修改历史列表:
|
||||
------------------------------------------------------------------------
|
||||
|
||||
416) 2014.1.19
|
||||
416.1) performance: acl_pthread_pool.c,由原来线程池统一用一个线程条件变量改
|
||||
为每个线程一个单独的线程条件变量,从而大大减少线程之间的锁冲突,因而提高了
|
||||
线程池的运行性能
|
||||
|
||||
415) 2014.1.11
|
||||
415.1) compile: 去掉了 ACL_MS_WINDOWS 宏定义,在WINDOWS环境下统一使用 WIN32
|
||||
来标识 VC 编译环境
|
||||
|
@ -19,6 +19,7 @@ typedef struct acl_pthread_job_t acl_pthread_job_t;
|
||||
* 创建一个线程池的工作任务
|
||||
* @param run_fn {void (*)(void*)} 在子线程中被调用的回调函数
|
||||
* @param run_arg {void*} run_fn 的回调参数之一
|
||||
* @param fixed {int}
|
||||
* @return {acl_pthread_job_t*} 返回创建的工作任务
|
||||
*/
|
||||
ACL_API acl_pthread_job_t *acl_pthread_pool_alloc_job(void (*run_fn)(void*),
|
||||
@ -41,9 +42,9 @@ typedef struct acl_pthread_pool_t acl_pthread_pool_t;
|
||||
typedef struct acl_pthread_pool_attr_t {
|
||||
int threads_limit; /**< 线程池最大线程数限制 */
|
||||
#define ACL_PTHREAD_POOL_DEF_THREADS 100 /**< 缺省最大值为 100 个线程 */
|
||||
int idle_timeout; /**< 工作线程空闲超时时间(秒) */
|
||||
#define ACL_PTHREAD_POOL_DEF_IDLE 60 /**< 缺省空间超时时间为 60 秒 */
|
||||
size_t stack_size; /**< 工作线程的堆栈大小(字节) */
|
||||
int idle_timeout; /**< 工作线程空闲超时时间(秒) */
|
||||
#define ACL_PTHREAD_POOL_DEF_IDLE 0 /**< 缺省空间超时时间为 0 秒 */
|
||||
size_t stack_size; /**< 工作线程的堆栈大小(字节) */
|
||||
} acl_pthread_pool_attr_t;
|
||||
|
||||
/**
|
||||
@ -111,38 +112,46 @@ ACL_API int acl_pthread_pool_stop(acl_pthread_pool_t *thr_pool);
|
||||
* @param thr_pool {acl_pthread_pool_t*} 线程池对象,不能为空
|
||||
* @param run_fn {void (*)(*)} 当有可用工作线程时所调用的回调处理函数
|
||||
* @param run_arg {void*} 回调函数 run_fn 所需要的回调参数
|
||||
* @return {int} 0: 成功; != 0: 失败
|
||||
*/
|
||||
ACL_API int acl_pthread_pool_add(acl_pthread_pool_t *thr_pool,
|
||||
void (*run_fn)(void *), void *run_arg);
|
||||
|
||||
/**
|
||||
* 开始进行批处理方式的添加任务, 实际上是开始进行加锁
|
||||
* @param thr_pool {acl_pthread_pool_t*} 线程池对象,不能为空
|
||||
*/
|
||||
ACL_API void acl_pthread_pool_add_begin(acl_pthread_pool_t *thr_pool);
|
||||
|
||||
/**
|
||||
* 添加一个新任务, 前提是已经成功加锁, 即调用acl_pthread_pool_add_begin 成功
|
||||
* @param thr_pool {acl_pthread_pool_t*} 线程池对象,不能为空
|
||||
* @param run_fn {void (*)(void*)} 当有可用工作线程时所调用的回调处理函数
|
||||
* @param run_arg 回调函数 run_fn 所需要的回调参数
|
||||
*/
|
||||
ACL_API void acl_pthread_pool_add_one(acl_pthread_pool_t *thr_pool,
|
||||
void (*run_fn)(void *), void *run_arg);
|
||||
#define acl_pthread_pool_add acl_pthread_pool_add_one
|
||||
|
||||
/**
|
||||
* 添加一个新任务, 前提是已经成功加锁, 即调用acl_pthread_pool_add_begin 成功
|
||||
* 向线程池添加一个任务
|
||||
* @param thr_pool {acl_pthread_pool_t*} 线程池对象,不能为空
|
||||
* @param job {acl_pthread_job_t*} 由 acl_pthread_pool_alloc_job 创建的线程任务
|
||||
*/
|
||||
ACL_API void acl_pthread_pool_add_job(acl_pthread_pool_t *thr_pool,
|
||||
acl_pthread_job_t *job);
|
||||
|
||||
/**
|
||||
* 开始进行批处理方式的添加任务, 实际上是开始进行加锁
|
||||
* @param thr_pool {acl_pthread_pool_t*} 线程池对象,不能为空
|
||||
*/
|
||||
ACL_API void acl_pthread_pool_bat_add_begin(acl_pthread_pool_t *thr_pool);
|
||||
|
||||
/**
|
||||
* 添加一个新任务, 前提是已经成功加锁, 即调用 acl_pthread_pool_bat_add_begin 成功
|
||||
* @param thr_pool {acl_pthread_pool_t*} 线程池对象,不能为空
|
||||
* @param run_fn {void (*)(void*)} 当有可用工作线程时所调用的回调处理函数
|
||||
* @param run_arg 回调函数 run_fn 所需要的回调参数
|
||||
*/
|
||||
ACL_API void acl_pthread_pool_bat_add_one(acl_pthread_pool_t *thr_pool,
|
||||
void (*run_fn)(void *), void *run_arg);
|
||||
/**
|
||||
* 添加一个新任务, 前提是已经成功加锁, 即调用 acl_pthread_pool_bat_add_begin 成功
|
||||
* @param thr_pool {acl_pthread_pool_t*} 线程池对象,不能为空
|
||||
* @param job {acl_pthread_job_t*} 由 acl_pthread_pool_alloc_job 创建的线程任务
|
||||
*/
|
||||
ACL_API void acl_pthread_pool_bat_add_job(acl_pthread_pool_t *thr_pool,
|
||||
acl_pthread_job_t *job);
|
||||
|
||||
/**
|
||||
* 批处理添加结束, 实际是解锁
|
||||
* @param thr_pool {acl_pthread_pool_t*} 线程池对象,不能为空
|
||||
*/
|
||||
ACL_API void acl_pthread_pool_add_end(acl_pthread_pool_t *thr_pool);
|
||||
ACL_API void acl_pthread_pool_bat_add_end(acl_pthread_pool_t *thr_pool);
|
||||
|
||||
/**
|
||||
* 设置线程池 POLLER 调度函数,若要使用此功能,需要在用函数
|
||||
|
@ -114,7 +114,6 @@ int acl_ioctl_add(ACL_IOCTL *ioc, ACL_IOCTL_WORKER_FN callback, void *arg)
|
||||
{
|
||||
const char *myname = "acl_ioctl_add";
|
||||
ACL_IOCTL_CTX *ctx;
|
||||
int ret;
|
||||
|
||||
if (ioc == NULL || ioc->tp == NULL)
|
||||
acl_msg_fatal("%s(%d): input invalid", myname, __LINE__);
|
||||
@ -124,13 +123,8 @@ int acl_ioctl_add(ACL_IOCTL *ioc, ACL_IOCTL_WORKER_FN callback, void *arg)
|
||||
ctx->worker_fn = callback;
|
||||
ctx->context = arg;
|
||||
|
||||
ret = acl_pthread_pool_add(ioc->tp, worker_ready_callback, ctx);
|
||||
if (ret != 0) {
|
||||
acl_msg_error("thread pool add failed!");
|
||||
acl_myfree(ctx);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
acl_pthread_pool_add(ioc->tp, worker_ready_callback, ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acl_ioctl_nworker(ACL_IOCTL *ioc)
|
||||
|
@ -96,11 +96,7 @@ void master_warning(const char *notify_addr, const char *recipients,
|
||||
}
|
||||
|
||||
info = warn_info_new(notify_addr, recipients, path, pid, desc);
|
||||
if (acl_pthread_pool_add(acl_var_master_thread_pool,
|
||||
notify_thread, info) != 0)
|
||||
{
|
||||
warn_info_free(info);
|
||||
}
|
||||
acl_pthread_pool_add(acl_var_master_thread_pool, notify_thread, info);
|
||||
}
|
||||
|
||||
#endif /* ACL_UNIX */
|
||||
|
@ -427,11 +427,7 @@ static void read_callback1(int event_type, ACL_EVENT *event acl_unused,
|
||||
{
|
||||
READ_CTX *ctx = (READ_CTX*) context;
|
||||
ctx->event_type = event_type;
|
||||
#if 1
|
||||
acl_pthread_pool_add_job(ctx->threads, ctx->job);
|
||||
#else
|
||||
acl_pthread_pool_add_one(ctx->threads, thread_callback, ctx);
|
||||
#endif
|
||||
acl_pthread_pool_bat_add_job(ctx->threads, ctx->job);
|
||||
}
|
||||
|
||||
static void read_callback2(int event_type, ACL_EVENT *event acl_unused,
|
||||
@ -439,20 +435,19 @@ static void read_callback2(int event_type, ACL_EVENT *event acl_unused,
|
||||
{
|
||||
READ_CTX *ctx = (READ_CTX*) context;
|
||||
ctx->event_type = event_type;
|
||||
|
||||
acl_pthread_pool_add(ctx->threads, thread_callback, ctx);
|
||||
acl_pthread_pool_add_job(ctx->threads, ctx->job);
|
||||
}
|
||||
|
||||
static void event_fire_begin(ACL_EVENT *event acl_unused, void *ctx)
|
||||
{
|
||||
acl_pthread_pool_t *threads = (acl_pthread_pool_t*) ctx;
|
||||
acl_pthread_pool_add_begin(threads);
|
||||
acl_pthread_pool_bat_add_begin(threads);
|
||||
}
|
||||
|
||||
static void event_fire_end(ACL_EVENT *event acl_unused, void *ctx)
|
||||
{
|
||||
acl_pthread_pool_t *threads = (acl_pthread_pool_t*) ctx;
|
||||
acl_pthread_pool_add_end(threads);
|
||||
acl_pthread_pool_bat_add_end(threads);
|
||||
}
|
||||
|
||||
static void free_ctx(ACL_VSTREAM *stream acl_unused, void *context)
|
||||
@ -484,15 +479,12 @@ static void server_execute(ACL_EVENT *event, acl_pthread_pool_t *threads,
|
||||
ctx->event_type = -1;
|
||||
ctx->serv_callback = __service_main;
|
||||
ctx->serv_arg = __service_ctx;
|
||||
ctx->job = acl_pthread_pool_alloc_job(thread_callback, ctx, 1);
|
||||
|
||||
if (acl_var_threads_batadd) {
|
||||
ctx->job = acl_pthread_pool_alloc_job(thread_callback,
|
||||
ctx, 1);
|
||||
if (acl_var_threads_batadd)
|
||||
ctx->read_callback = read_callback1;
|
||||
} else {
|
||||
ctx->job = NULL;
|
||||
else
|
||||
ctx->read_callback = read_callback2;
|
||||
}
|
||||
|
||||
stream->ioctl_read_ctx = ctx;
|
||||
acl_vstream_add_close_handle(stream, free_ctx, ctx);
|
||||
|
File diff suppressed because it is too large
Load Diff
1122
lib_acl/src/thread/acl_pthread_pool.c.bak
Normal file
1122
lib_acl/src/thread/acl_pthread_pool.c.bak
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,5 @@
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
#include "lib_acl.h"
|
||||
#include "acl_cpp/acl_cpp_init.hpp"
|
||||
#include "acl_cpp/stdlib/string.hpp"
|
||||
#include "acl_cpp/stdlib/util.hpp"
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
#include "lib_acl.h"
|
||||
#include "acl_cpp/acl_cpp_init.hpp"
|
||||
#include "acl_cpp/stream/aio_handle.hpp"
|
||||
#include "acl_cpp/stream/aio_istream.hpp"
|
||||
#include "acl_cpp/stream/aio_listen_stream.hpp"
|
||||
@ -276,7 +276,7 @@ int main(int argc, char* argv[])
|
||||
const char* addr = "127.0.0.1:9001";
|
||||
|
||||
// 初始化ACL库(尤其是在WIN32下一定要调用此函数,在UNIX平台下可不调用)
|
||||
acl_init();
|
||||
acl::acl_cpp_init();
|
||||
|
||||
// 监听指定的地址
|
||||
if (sstream->open(addr) == false)
|
||||
@ -295,7 +295,6 @@ int main(int argc, char* argv[])
|
||||
sstream->add_accept_callback(&callback);
|
||||
std::cout << "Listen: " << addr << " ok!" << std::endl;
|
||||
|
||||
#if 1
|
||||
while (true)
|
||||
{
|
||||
// 如果返回 false 则表示不再继续,需要退出
|
||||
@ -305,7 +304,7 @@ int main(int argc, char* argv[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// 关闭监听流并释放流对象
|
||||
sstream->close();
|
||||
|
||||
|
2
lib_acl_cpp/samples/mmap/Makefile
Normal file
2
lib_acl_cpp/samples/mmap/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
PROG = mmap_test
|
||||
include ../Makefile.in
|
115
lib_acl_cpp/samples/mmap/main.cpp
Normal file
115
lib_acl_cpp/samples/mmap/main.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
#include "stdafx.h"
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
static acl::string __fpath("./tmp.dmp");
|
||||
static off_t __max = 1000000;
|
||||
|
||||
static void* thread_main(void* arg)
|
||||
{
|
||||
sleep(10);
|
||||
|
||||
printf("thread started\r\n");
|
||||
char* ptr = (char*) arg;
|
||||
for (off_t i = 0; i < __max; i++)
|
||||
{
|
||||
int ch = *ptr++;
|
||||
if (i % 9999999 == 0)
|
||||
printf("get ch: %c\r\n", ch);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usage(const char* procname)
|
||||
{
|
||||
printf("usage: %s -h [help] -f file_path -n file_size -u [call munmap] -o get|set\r\n", procname);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
acl::string action("get");
|
||||
bool unuse = false;
|
||||
int ch;
|
||||
|
||||
while ((ch = getopt(argc, argv, "hf:n:uo:")) > 0)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
case 'f':
|
||||
__fpath = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
__max = atol(optarg);
|
||||
break;
|
||||
case 'u':
|
||||
unuse = true;
|
||||
break;
|
||||
case 'o':
|
||||
action = optarg;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int fd = open(__fpath.c_str(), O_RDWR | O_CREAT, 0600);
|
||||
if (fd == -1)
|
||||
{
|
||||
printf("open %s error\r\n", __fpath.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
char* ptr = (char*) mmap(NULL, __max, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
printf("mmap error %s\r\n", acl::last_serror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("file size: %ld\r\n", __max);
|
||||
lseek(fd, __max, SEEK_SET);
|
||||
write(fd, "x", 1);
|
||||
close(fd);
|
||||
char* ptr_saved = ptr;
|
||||
|
||||
printf("action: %s\r\n", action.c_str());
|
||||
|
||||
if (action == "get")
|
||||
{
|
||||
for (off_t i = 0; i < __max; i++)
|
||||
{
|
||||
ch = *ptr++;
|
||||
if (i % 9999999 == 0)
|
||||
printf("ch: %d, %c, i: %ld\n", ch, ch, i);
|
||||
}
|
||||
}
|
||||
else if (action == "set")
|
||||
{
|
||||
acl_pthread_t tid;
|
||||
acl_pthread_create(&tid, NULL, thread_main, ptr);
|
||||
|
||||
for (off_t i = 0; i < __max; i++)
|
||||
{
|
||||
if (i % 100 == 0)
|
||||
*ptr = '\n';
|
||||
else
|
||||
*ptr = 'x';
|
||||
if (i % 9999999 == 0)
|
||||
printf("set: %c\r\n", *ptr);
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
printf("unknown action: %s\r\n", action.c_str());
|
||||
|
||||
if (unuse)
|
||||
munmap(ptr_saved, __max);
|
||||
sleep(100);
|
||||
return 0;
|
||||
}
|
8
lib_acl_cpp/samples/mmap/stdafx.cpp
Normal file
8
lib_acl_cpp/samples/mmap/stdafx.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
// stdafx.cpp : 只包括标准包含文件的源文件
|
||||
// xml.pch 将成为预编译头
|
||||
// stdafx.obj 将包含预编译类型信息
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: 在 STDAFX.H 中
|
||||
//引用任何所需的附加头文件,而不是在此文件中引用
|
13
lib_acl_cpp/samples/mmap/stdafx.h
Normal file
13
lib_acl_cpp/samples/mmap/stdafx.h
Normal file
@ -0,0 +1,13 @@
|
||||
// stdafx.h : 标准系统包含文件的包含文件,
|
||||
// 或是常用但不常更改的项目特定的包含文件
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
//#include <iostream>
|
||||
//#include <tchar.h>
|
||||
|
||||
// TODO: 在此处引用程序要求的附加头文件
|
||||
#include "acl_cpp/lib_acl.hpp"
|
||||
#include "lib_acl.h"
|
@ -87,8 +87,8 @@ bool thread_pool::run(thread_job* job)
|
||||
return false;
|
||||
}
|
||||
|
||||
return acl_pthread_pool_add(thr_pool_, thread_run, job)
|
||||
== 0 ? true : false;
|
||||
acl_pthread_pool_add(thr_pool_, thread_run, job);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool thread_pool::execute(thread_job* job)
|
||||
|
@ -7,10 +7,9 @@ all:
|
||||
@(cd event; make)
|
||||
@(cd fifo; make)
|
||||
@(cd mempool; make)
|
||||
# @(cd thread; make)
|
||||
@(cd thread; make)
|
||||
@(cd debug_malloc; make)
|
||||
@(cd mempool; make)
|
||||
# @(cd thread_pool; make)
|
||||
@(cd vstream; make)
|
||||
@(cd vstream_unread; make)
|
||||
@(cd vstream_fseek; make)
|
||||
@ -65,7 +64,6 @@ all:
|
||||
# @(cd jt2ft; make)
|
||||
@(cd acl; make)
|
||||
# @(cd dbpool; make)
|
||||
@(cd thread_pool_client; make)
|
||||
@(cd smtp_client; make)
|
||||
@(cd vstream_popen3; make)
|
||||
@(cd mkdir; make)
|
||||
@ -84,7 +82,6 @@ clean:
|
||||
@(cd thread; make clean)
|
||||
@(cd debug_malloc; make clean)
|
||||
@(cd mempool; make clean)
|
||||
# @(cd thread_pool; make clean)
|
||||
@(cd vstream; make clean)
|
||||
@(cd vstream_unread; make clean)
|
||||
@(cd vstream_fseek; make clean)
|
||||
@ -141,7 +138,6 @@ clean:
|
||||
@(cd acl; make clean)
|
||||
# @(cd dbpool; make clean)
|
||||
@(cd http_probe; make clean)
|
||||
@(cd thread_pool_client; make clean)
|
||||
@(cd gc; make clean)
|
||||
@(cd smtp_client; make clean)
|
||||
@(cd vstream_popen3; make clean)
|
||||
|
2
samples/json3/Makefile
Normal file
2
samples/json3/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
include ../Makefile_cpp.in
|
||||
PROG = json
|
124
samples/json3/main.cpp
Normal file
124
samples/json3/main.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
#include "lib_acl.h"
|
||||
|
||||
#define STR acl_vstring_str
|
||||
#define LEN ACL_VSTRING_LEN
|
||||
|
||||
#if 0
|
||||
|
||||
static const char *__json_string =
|
||||
"{\r\n"
|
||||
" id: 'file', value: 'File',\r\n"
|
||||
" popup: {\r\n"
|
||||
" menuitem: [\r\n"
|
||||
" { value: 'New', onclick: 'CreateNewDoc()' },\r\n"
|
||||
" { value: 'Open', onclick: 'OpenDoc()' },\r\n"
|
||||
" { value: 'Close', onclick: 'CloseDoc()' }\r\n"
|
||||
" ],\r\n"
|
||||
" menuitem: 'help'\r\n"
|
||||
" },\r\n"
|
||||
" help: 'hello world!'\r\n"
|
||||
"}\r\n";
|
||||
|
||||
#else
|
||||
|
||||
static const char *__json_string =
|
||||
"{\"header\": {\"cmd\": \"8201\", \"tel\": \"011031000026\"}, \"body\" :{}}";
|
||||
|
||||
#endif
|
||||
|
||||
static void parse_json(const char *data)
|
||||
{
|
||||
ACL_JSON *json = acl_json_alloc();
|
||||
ACL_VSTRING *buf1 = acl_vstring_alloc(128);
|
||||
ACL_VSTRING *buf2 = acl_vstring_alloc(128);
|
||||
ACL_ARRAY *nodes;
|
||||
const char *tag = "header";
|
||||
|
||||
printf("buf src: %s\r\n", data);
|
||||
|
||||
printf("------------------------------------------------\r\n");
|
||||
|
||||
acl_json_update(json, data);
|
||||
acl_json_build(json, buf1);
|
||||
printf("result src: %s\r\n", STR(buf1));
|
||||
|
||||
printf("------------------------------------------------\r\n");
|
||||
|
||||
nodes = acl_json_getElementsByTagName(json, tag);
|
||||
if (nodes == NULL)
|
||||
{
|
||||
printf("not found tag: %s\r\n", tag);
|
||||
acl_vstring_free(buf1);
|
||||
acl_vstring_free(buf2);
|
||||
acl_json_free(json);
|
||||
return;
|
||||
}
|
||||
|
||||
printf(">>>tag: %s, len: %d\r\n", tag, acl_array_size(nodes));
|
||||
|
||||
ACL_ITER iter;
|
||||
|
||||
#define STR acl_vstring_str
|
||||
#define LEN ACL_VSTRING_LEN
|
||||
|
||||
acl_foreach(iter, nodes)
|
||||
{
|
||||
ACL_JSON_NODE *node = (ACL_JSON_NODE*) iter.data;
|
||||
ACL_JSON_NODE *tag_node = node->tag_node;
|
||||
if (tag_node == NULL)
|
||||
continue;
|
||||
|
||||
printf(">>>tag: %s\r\n", STR(node->ltag));
|
||||
|
||||
ACL_ITER iter2;
|
||||
acl_foreach(iter2, tag_node)
|
||||
{
|
||||
ACL_JSON_NODE *node1 = (ACL_JSON_NODE*) iter2.data;
|
||||
if (node1->ltag == NULL || LEN(node1->ltag) == 0)
|
||||
continue;
|
||||
printf(">>>child tag: %s, txt: %s\r\n", STR(node1->ltag),
|
||||
node1->text ? STR(node1->text) : "null");
|
||||
}
|
||||
}
|
||||
|
||||
if (nodes)
|
||||
acl_json_free_array(nodes);
|
||||
|
||||
acl_json_free(json);
|
||||
acl_vstring_free(buf1);
|
||||
acl_vstring_free(buf2);
|
||||
}
|
||||
|
||||
static void usage(const char *procname)
|
||||
{
|
||||
printf("usage: %s -h [help]\r\n", procname);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int ch;
|
||||
char filepath[256];
|
||||
|
||||
filepath[0] = 0;
|
||||
|
||||
while ((ch = getopt(argc, argv, "h")) > 0) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (filepath[0]) {
|
||||
char *data = acl_vstream_loadfile(filepath);
|
||||
if (data) {
|
||||
parse_json(data);
|
||||
acl_myfree(data);
|
||||
}
|
||||
} else
|
||||
parse_json(__json_string);
|
||||
|
||||
return 0;
|
||||
}
|
3
samples/json3/valgrind.sh
Normal file
3
samples/json3/valgrind.sh
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
valgrind --tool=memcheck --leak-check=yes -v ./json -b -m 10
|
@ -35,7 +35,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mempool", "mempool\mempool_
|
||||
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "thread", "thread\thread_vc2003.vcproj", "{DF044F15-C15D-4C69-9024-21235BC3C7E9}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "thread", "thread\thread1\thread_vc2003.vcproj", "{DF044F15-C15D-4C69-9024-21235BC3C7E9}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
|
||||
EndProjectSection
|
||||
@ -55,7 +55,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vstring", "vstring\vstring_
|
||||
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "thread_pool", "thread_pool\thread_pool_vc2003.vcproj", "{143D67EE-85E1-4456-AD99-6FDE7B1F1469}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "thread_pool", "thread\thread_pool1\thread_pool_vc2003.vcproj", "{143D67EE-85E1-4456-AD99-6FDE7B1F1469}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
|
||||
EndProjectSection
|
||||
|
@ -36,7 +36,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mempool", "mempool\mempool.
|
||||
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "thread", "thread\thread.vcxproj", "{DF044F15-C15D-4C69-9024-21235BC3C7E9}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "thread", "thread\thread1\thread.vcxproj", "{DF044F15-C15D-4C69-9024-21235BC3C7E9}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
|
||||
EndProjectSection
|
||||
@ -56,7 +56,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vstring", "vstring\vstring.
|
||||
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "thread_pool", "thread_pool\thread_pool.vcxproj", "{143D67EE-85E1-4456-AD99-6FDE7B1F1469}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "thread_pool", "thread\thread_pool1\thread_pool.vcxproj", "{143D67EE-85E1-4456-AD99-6FDE7B1F1469}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
|
||||
EndProjectSection
|
||||
|
@ -1,2 +1,10 @@
|
||||
include ../Makefile.in
|
||||
PROG = thread
|
||||
all:
|
||||
@(cd thread1; make)
|
||||
@(cd thread_pool1; make)
|
||||
@(cd thread_pool2; make)
|
||||
@(cd thread_pool3; make)
|
||||
clean:
|
||||
@(cd thread1; make clean)
|
||||
@(cd thread_pool1; make clean)
|
||||
@(cd thread_pool2; make clean)
|
||||
@(cd thread_pool3; make clean)
|
||||
|
112
samples/thread/Makefile.in
Normal file
112
samples/thread/Makefile.in
Normal file
@ -0,0 +1,112 @@
|
||||
CC = gcc
|
||||
|
||||
CFLAGS = -c -g -W -Wall -Wcast-qual -Wcast-align \
|
||||
-Waggregate-return -Wno-long-long -Wmissing-prototypes \
|
||||
-Wpointer-arith -Werror -Wshadow -O2 \
|
||||
-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -D_USE_FAST_MACRO
|
||||
|
||||
#CFLAGS = -c -g -W -Wall -Wcast-qual -Wcast-align \
|
||||
#-Waggregate-return -Wmissing-prototypes \
|
||||
#-Wpointer-arith -Werror -Wshadow -O2 \
|
||||
#-D_POSIX_PTHREAD_SEMANTICS -D_USE_FAST_MACRO
|
||||
###########################################################
|
||||
#Check system:
|
||||
# Linux, SunOS, Solaris, BSD variants, AIX, HP-UX
|
||||
SYSLIB = -lpthread
|
||||
CHECKSYSRES = @echo "Unknow system type!";exit 1
|
||||
UNIXNAME = $(shell uname -sm)
|
||||
|
||||
ifeq ($(CC),)
|
||||
CC = gcc
|
||||
endif
|
||||
|
||||
ifeq ($(findstring gcc, $(CC)), gcc)
|
||||
CFLAGS += -Wstrict-prototypes
|
||||
endif
|
||||
|
||||
# For FreeBSD
|
||||
ifeq ($(findstring FreeBSD, $(UNIXNAME)), FreeBSD)
|
||||
CFLAGS += -DFREEBSD -D_REENTRANT
|
||||
SYSLIB += -lcrypt
|
||||
endif
|
||||
|
||||
#Path for Linux
|
||||
ifeq ($(findstring Linux, $(UNIXNAME)), Linux)
|
||||
CFLAGS += -DLINUX2 -D_REENTRANT
|
||||
SYSLIB += -lcrypt
|
||||
endif
|
||||
|
||||
# For Darwin
|
||||
ifeq ($(findstring Darwin, $(UNIXNAME)), Darwin)
|
||||
CFLAGS += -DMACOSX
|
||||
endif
|
||||
|
||||
#Path for SunOS
|
||||
ifeq ($(findstring SunOS, $(UNIXNAME)), SunOS)
|
||||
ifeq ($(findstring 86, $(UNIXNAME)), 86)
|
||||
SYSLIB += -lsocket -lnsl -lrt
|
||||
endif
|
||||
ifeq ($(findstring sun4u, $(UNIXNAME)), sun4u)
|
||||
SYSLIB += -lsocket -lnsl -lrt
|
||||
endif
|
||||
CFLAGS += -DSUNOS5 -D_REENTRANT
|
||||
SYSLIB += -lcrypt
|
||||
endif
|
||||
|
||||
#Path for HP-UX
|
||||
ifeq ($(findstring HP-UX, $(UNIXNAME)), HP-UX)
|
||||
ifeq ($CC, "gcc")
|
||||
CFLAGS += -Wstrict-prototypes
|
||||
endif
|
||||
CFLAGS += -DHP_UX -DHPUX11
|
||||
PLAT_NAME=hp-ux
|
||||
SYSLIB += -lcrypt
|
||||
endif
|
||||
|
||||
#Find system type.
|
||||
ifneq ($(SYSPATH),)
|
||||
CHECKSYSRES = @echo "System is $(shell uname -sm)"
|
||||
endif
|
||||
###########################################################
|
||||
|
||||
ACL_PATH = ../../../lib_acl
|
||||
ACL_INC = $(ACL_PATH)/include
|
||||
ACL_LIB = $(ACL_PATH)/lib
|
||||
|
||||
PROTO_PATH = ../../../lib_protocol
|
||||
PROTO_INC = $(PROTO_PATH)/include
|
||||
PROTO_LIB = $(PROTO_PATH)/lib
|
||||
|
||||
EXTLIBS =
|
||||
CFLAGS += -I$(ACL_INC) -I$(PROTO_INC)
|
||||
LDFLAGS = -L$(ACL_LIB) -L$(PROTO_LIB) -l_protocol -l_acl $(EXTLIBS) $(SYSLIB)
|
||||
|
||||
###########################################################
|
||||
|
||||
OUT_PATH = .
|
||||
OBJ_PATH = $(OUT_PATH)
|
||||
|
||||
#Project's objs
|
||||
SRC = $(wildcard *.c)
|
||||
OBJ = $(patsubst %.c, $(OBJ_PATH)/%.o, $(notdir $(SRC)))
|
||||
###########################################################
|
||||
|
||||
.PHONY = all clean
|
||||
PROG =
|
||||
|
||||
COMPILE = $(CC) $(CFLAGS)
|
||||
|
||||
#-Wl,-rpath,$(ACL_LIB) -Wl,-rpath,$(PROTO_LIB) -o $(OBJ_PATH)/$(PROG)
|
||||
all: RM $(OBJ)
|
||||
$(CC) $(OBJ) $(LDFLAGS) -o $(OBJ_PATH)/$(PROG)
|
||||
@echo ""
|
||||
@echo "All ok! Output:$(PROG)"
|
||||
@echo ""
|
||||
$(OBJ_PATH)/%.o: %.c
|
||||
$(COMPILE) $< -o $@
|
||||
RM:
|
||||
rm -f $(PROG)
|
||||
clean:
|
||||
rm -f $(PROG)
|
||||
rm -f $(OBJ)
|
||||
###########################################################
|
105
samples/thread/Makefile_cpp.in
Normal file
105
samples/thread/Makefile_cpp.in
Normal file
@ -0,0 +1,105 @@
|
||||
CC = g++
|
||||
|
||||
CFLAGS = -c -g -W -Wall -Wcast-qual -Wcast-align \
|
||||
-Waggregate-return -Wno-long-long \
|
||||
-Wpointer-arith -Werror -Wshadow -O2 \
|
||||
-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -D_USE_FAST_MACRO
|
||||
|
||||
###########################################################
|
||||
#Check system:
|
||||
# Linux, SunOS, Solaris, BSD variants, AIX, HP-UX
|
||||
SYSLIB = -lpthread
|
||||
CHECKSYSRES = @echo "Unknow system type!";exit 1
|
||||
UNIXNAME = $(shell uname -sm)
|
||||
|
||||
ifeq ($(CC),)
|
||||
CC = gcc
|
||||
endif
|
||||
|
||||
ifeq ($(findstring gcc, $(CC)), gcc)
|
||||
CFLAGS += -Wstrict-prototypes
|
||||
endif
|
||||
|
||||
# For FreeBSD
|
||||
ifeq ($(findstring FreeBSD, $(UNIXNAME)), FreeBSD)
|
||||
CFLAGS += -DFREEBSD -D_REENTRANT -pedantic
|
||||
SYSLIB += -lcrypt
|
||||
endif
|
||||
|
||||
#Path for Linux
|
||||
ifeq ($(findstring Linux, $(UNIXNAME)), Linux)
|
||||
CFLAGS += -DLINUX2 -D_REENTRANT -pedantic
|
||||
SYSLIB += -lcrypt
|
||||
endif
|
||||
|
||||
#Path for SunOS
|
||||
ifeq ($(findstring SunOS, $(UNIXNAME)), SunOS)
|
||||
ifeq ($(findstring 86, $(UNIXNAME)), 86)
|
||||
SYSLIB += -lsocket -lnsl -lrt
|
||||
endif
|
||||
ifeq ($(findstring sun4u, $(UNIXNAME)), sun4u)
|
||||
SYSLIB += -lsocket -lnsl -lrt
|
||||
endif
|
||||
CFLAGS += -DSUNOS5 -D_REENTRANT -pedantic
|
||||
SYSLIB += -lcrypt
|
||||
endif
|
||||
|
||||
#Path for HP-UX
|
||||
ifeq ($(findstring HP-UX, $(UNIXNAME)), HP-UX)
|
||||
CFLAGS += -DHP_UX -DHPUX11
|
||||
PLAT_NAME=hp-ux
|
||||
SYSLIB += -lcrypt
|
||||
endif
|
||||
|
||||
# For Darwin
|
||||
ifeq ($(findstring Darwin, $(UNIXNAME)), Darwin)
|
||||
CFLAGS += -DMACOSX
|
||||
endif
|
||||
|
||||
#Find system type.
|
||||
ifneq ($(SYSPATH),)
|
||||
CHECKSYSRES = @echo "System is $(shell uname -sm)"
|
||||
endif
|
||||
###########################################################
|
||||
|
||||
ACL_PATH = ../../../lib_acl
|
||||
ACL_INC = $(ACL_PATH)/include
|
||||
ACL_LIB = $(ACL_PATH)/lib
|
||||
|
||||
PROTO_PATH = ../../../lib_protocol
|
||||
PROTO_INC = $(PROTO_PATH)/include
|
||||
PROTO_LIB = $(PROTO_PATH)/lib
|
||||
|
||||
EXTLIBS =
|
||||
CFLAGS += -I$(ACL_INC) -I$(PROTO_INC)
|
||||
LDFLAGS = -L$(ACL_LIB) -L$(PROTO_LIB) -l_protocol -l_acl $(EXTLIBS) $(SYSLIB)
|
||||
|
||||
###########################################################
|
||||
|
||||
OUT_PATH = .
|
||||
OBJ_PATH = $(OUT_PATH)
|
||||
|
||||
#Project's objs
|
||||
SRC = $(wildcard *.cpp)
|
||||
OBJ = $(patsubst %.cpp, $(OBJ_PATH)/%.o, $(notdir $(SRC)))
|
||||
###########################################################
|
||||
|
||||
.PHONY = all clean
|
||||
PROG =
|
||||
|
||||
COMPILE = $(CC) $(CFLAGS)
|
||||
|
||||
# -Wl,-rpath,$(ACL_LIB) -Wl,-rpath,$(PROTO_LIB) -o $(OBJ_PATH)/$(PROG)
|
||||
all: RM $(OBJ)
|
||||
$(CC) $(OBJ) $(LDFLAGS) -o $(OBJ_PATH)/$(PROG)
|
||||
@echo ""
|
||||
@echo "All ok! Output:$(PROG)"
|
||||
@echo ""
|
||||
$(OBJ_PATH)/%.o: %.cpp
|
||||
$(COMPILE) $< -o $@
|
||||
RM:
|
||||
rm -f $(PROG)
|
||||
clean:
|
||||
rm -f $(PROG)
|
||||
rm -f $(OBJ)
|
||||
###########################################################
|
2
samples/thread/thread1/Makefile
Normal file
2
samples/thread/thread1/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
include ../Makefile.in
|
||||
PROG = thread
|
@ -86,7 +86,7 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
@ -108,7 +108,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
@ -130,7 +130,7 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;ACL_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
@ -152,7 +152,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;ACL_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
@ -172,7 +172,7 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\lib_acl\lib_acl_vc2010.vcxproj">
|
||||
<ProjectReference Include="..\..\..\lib_acl\lib_acl_vc2010.vcxproj">
|
||||
<Project>{b40213c2-507c-4c7f-a6e1-b850c9bdc27b}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
@ -183,4 +183,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
@ -19,7 +19,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\lib_acl\include"
|
||||
AdditionalIncludeDirectories="..\..\..\lib_acl\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
@ -35,7 +35,7 @@
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
OutputFile="$(OutDir)/thread.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="..\..\lib_acl"
|
||||
AdditionalLibraryDirectories="..\..\..\lib_acl"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/thread.pdb"
|
||||
SubSystem="1"
|
||||
@ -69,7 +69,7 @@
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..\..\lib_acl\include"
|
||||
AdditionalIncludeDirectories="..\..\..\lib_acl\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
@ -83,7 +83,7 @@
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
OutputFile="$(OutDir)/thread.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\..\lib_acl"
|
||||
AdditionalLibraryDirectories="..\..\..\lib_acl"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
@ -119,7 +119,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\lib_acl\include"
|
||||
AdditionalIncludeDirectories="..\..\..\lib_acl\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;ACL_DLL"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
@ -135,7 +135,7 @@
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
OutputFile="$(OutDir)/thread.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="..\..\lib_acl"
|
||||
AdditionalLibraryDirectories="..\..\..\lib_acl"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/thread.pdb"
|
||||
SubSystem="1"
|
||||
@ -169,7 +169,7 @@
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..\..\lib_acl\include"
|
||||
AdditionalIncludeDirectories="..\..\..\lib_acl\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;ACL_DLL"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
@ -183,7 +183,7 @@
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
OutputFile="$(OutDir)/thread.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\..\lib_acl"
|
||||
AdditionalLibraryDirectories="..\..\..\lib_acl"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
@ -1,112 +1,112 @@
|
||||
#include "stdlib/acl_define_unix.h"
|
||||
#ifdef ACL_UNIX
|
||||
# ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
# endif
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "lib_acl.h"
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
static void *thread_main(void *arg acl_unused)
|
||||
{
|
||||
pid_t pid;
|
||||
acl_pthread_mutex_t *__lock;
|
||||
int ret;
|
||||
char ebuf[256];
|
||||
|
||||
__lock = (acl_pthread_mutex_t*) acl_mycalloc(1,
|
||||
sizeof(acl_pthread_mutex_t));
|
||||
acl_pthread_mutex_init(__lock, NULL);
|
||||
|
||||
printf("current pid: %d, tid: %lu\r\n", getpid(), acl_pthread_self());
|
||||
|
||||
if ((ret = acl_pthread_mutex_lock(__lock)) == 0)
|
||||
printf("0: main thread(%lu) lock ok\r\n", acl_pthread_self());
|
||||
else
|
||||
printf("0: main thread(%lu) lock error(%d:%s)\r\n",
|
||||
acl_pthread_self(), ret,
|
||||
acl_strerror(ret, ebuf, sizeof(ebuf)));
|
||||
|
||||
switch ((pid = fork())) {
|
||||
case 0:
|
||||
/* 先解锁 */
|
||||
if ((ret = acl_pthread_mutex_unlock(__lock)) == 0)
|
||||
printf("1: child thread(%lu) unlock ok\r\n",
|
||||
acl_pthread_self());
|
||||
else
|
||||
printf("1: child thread(%lu) unlock error(%d:%s)\r\n",
|
||||
acl_pthread_self(), ret,
|
||||
acl_strerror(ret, ebuf, sizeof(ebuf)));
|
||||
|
||||
/* 再加锁 */
|
||||
if ((ret = acl_pthread_mutex_lock(__lock)) == 0)
|
||||
printf("1: child thread(%lu) lock ok\r\n",
|
||||
acl_pthread_self());
|
||||
else
|
||||
printf("1: child thread(%lu) lock error(%d:%s)\r\n",
|
||||
acl_pthread_self(), ret,
|
||||
acl_strerror(ret, ebuf, sizeof(ebuf)));
|
||||
|
||||
/* 再释放锁--该函数会报错 */
|
||||
if ((ret = acl_pthread_mutex_destroy(__lock)) == 0)
|
||||
printf("1: child thread(%lu) destroy ok\r\n",
|
||||
acl_pthread_self());
|
||||
else
|
||||
printf("1: child thread(%lu) destroy error(%d:%s)\r\n",
|
||||
acl_pthread_self(), ret,
|
||||
acl_strerror(ret, ebuf, sizeof(ebuf)));
|
||||
acl_myfree(__lock);
|
||||
exit (0);
|
||||
|
||||
case -1:
|
||||
printf("fork failed\r\n");
|
||||
exit (0);
|
||||
default:
|
||||
printf("0: parent, child pid: %d, tid: %lu\r\n",
|
||||
getpid(), acl_pthread_self());
|
||||
sleep(1);
|
||||
|
||||
{
|
||||
int status;
|
||||
pid_t pp;
|
||||
pp = wait(&status);
|
||||
printf("wait's pid: %d, pid: %d, status: %d\r\n",
|
||||
pp, pid, status);
|
||||
}
|
||||
|
||||
if ((ret = acl_pthread_mutex_destroy(__lock)) == 0)
|
||||
printf("0: parent thread(%lu) destroy lock ok\r\n",
|
||||
acl_pthread_self());
|
||||
else
|
||||
printf("0: parent thread(%lu) destroy err(%d:%s)\r\n",
|
||||
acl_pthread_self(), ret,
|
||||
acl_strerror(ret, ebuf, sizeof(ebuf)));
|
||||
acl_myfree(__lock);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void test_thread(void)
|
||||
{
|
||||
acl_pthread_attr_t attr;
|
||||
acl_pthread_t t1;
|
||||
|
||||
acl_pthread_attr_init(&attr);
|
||||
acl_pthread_attr_setstacksize(&attr, 10240000);
|
||||
acl_pthread_create(&t1, &attr, thread_main, NULL);
|
||||
acl_pthread_join(t1, NULL);
|
||||
printf(">>> test_pthread_once: over now, enter any key to exit...\n");
|
||||
getchar();
|
||||
}
|
||||
|
||||
int main(int argc acl_unused, char *argv[] acl_unused)
|
||||
{
|
||||
test_thread();
|
||||
return (0);
|
||||
}
|
||||
#include "stdlib/acl_define_unix.h"
|
||||
#ifdef ACL_UNIX
|
||||
# ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
# endif
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "lib_acl.h"
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
static void *thread_main(void *arg acl_unused)
|
||||
{
|
||||
pid_t pid;
|
||||
acl_pthread_mutex_t *__lock;
|
||||
int ret;
|
||||
char ebuf[256];
|
||||
|
||||
__lock = (acl_pthread_mutex_t*) acl_mycalloc(1,
|
||||
sizeof(acl_pthread_mutex_t));
|
||||
acl_pthread_mutex_init(__lock, NULL);
|
||||
|
||||
printf("current pid: %d, tid: %lu\r\n", getpid(), acl_pthread_self());
|
||||
|
||||
if ((ret = acl_pthread_mutex_lock(__lock)) == 0)
|
||||
printf("0: main thread(%lu) lock ok\r\n", acl_pthread_self());
|
||||
else
|
||||
printf("0: main thread(%lu) lock error(%d:%s)\r\n",
|
||||
acl_pthread_self(), ret,
|
||||
acl_strerror(ret, ebuf, sizeof(ebuf)));
|
||||
|
||||
switch ((pid = fork())) {
|
||||
case 0:
|
||||
/* 先解锁 */
|
||||
if ((ret = acl_pthread_mutex_unlock(__lock)) == 0)
|
||||
printf("1: child thread(%lu) unlock ok\r\n",
|
||||
acl_pthread_self());
|
||||
else
|
||||
printf("1: child thread(%lu) unlock error(%d:%s)\r\n",
|
||||
acl_pthread_self(), ret,
|
||||
acl_strerror(ret, ebuf, sizeof(ebuf)));
|
||||
|
||||
/* 再加锁 */
|
||||
if ((ret = acl_pthread_mutex_lock(__lock)) == 0)
|
||||
printf("1: child thread(%lu) lock ok\r\n",
|
||||
acl_pthread_self());
|
||||
else
|
||||
printf("1: child thread(%lu) lock error(%d:%s)\r\n",
|
||||
acl_pthread_self(), ret,
|
||||
acl_strerror(ret, ebuf, sizeof(ebuf)));
|
||||
|
||||
/* 再释放锁--该函数会报错 */
|
||||
if ((ret = acl_pthread_mutex_destroy(__lock)) == 0)
|
||||
printf("1: child thread(%lu) destroy ok\r\n",
|
||||
acl_pthread_self());
|
||||
else
|
||||
printf("1: child thread(%lu) destroy error(%d:%s)\r\n",
|
||||
acl_pthread_self(), ret,
|
||||
acl_strerror(ret, ebuf, sizeof(ebuf)));
|
||||
acl_myfree(__lock);
|
||||
exit (0);
|
||||
|
||||
case -1:
|
||||
printf("fork failed\r\n");
|
||||
exit (0);
|
||||
default:
|
||||
printf("0: parent, child pid: %d, tid: %lu\r\n",
|
||||
getpid(), acl_pthread_self());
|
||||
sleep(1);
|
||||
|
||||
{
|
||||
int status;
|
||||
pid_t pp;
|
||||
pp = wait(&status);
|
||||
printf("wait's pid: %d, pid: %d, status: %d\r\n",
|
||||
pp, pid, status);
|
||||
}
|
||||
|
||||
if ((ret = acl_pthread_mutex_destroy(__lock)) == 0)
|
||||
printf("0: parent thread(%lu) destroy lock ok\r\n",
|
||||
acl_pthread_self());
|
||||
else
|
||||
printf("0: parent thread(%lu) destroy err(%d:%s)\r\n",
|
||||
acl_pthread_self(), ret,
|
||||
acl_strerror(ret, ebuf, sizeof(ebuf)));
|
||||
acl_myfree(__lock);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void test_thread(void)
|
||||
{
|
||||
acl_pthread_attr_t attr;
|
||||
acl_pthread_t t1;
|
||||
|
||||
acl_pthread_attr_init(&attr);
|
||||
acl_pthread_attr_setstacksize(&attr, 10240000);
|
||||
acl_pthread_create(&t1, &attr, thread_main, NULL);
|
||||
acl_pthread_join(t1, NULL);
|
||||
printf(">>> test_pthread_once: over now, enter any key to exit...\n");
|
||||
getchar();
|
||||
}
|
||||
|
||||
int main(int argc acl_unused, char *argv[] acl_unused)
|
||||
{
|
||||
test_thread();
|
||||
return (0);
|
||||
}
|
@ -152,12 +152,16 @@ typedef struct {
|
||||
int i;
|
||||
} RUN_CTX;
|
||||
static acl_pthread_mutex_t __mutex;
|
||||
static int __i = 0;
|
||||
static void run_thread(void *arg)
|
||||
{
|
||||
RUN_CTX *ctx = (RUN_CTX*) arg;
|
||||
|
||||
acl_pthread_mutex_lock(&__mutex);
|
||||
acl_vstream_fprintf(ctx->fp, "hello world, hello world, hello world, hello world, i: %d\n", ctx->i);
|
||||
if (0)
|
||||
acl_vstream_fprintf(ctx->fp, "hello world, id: %d, i: %d\n", ctx->i, __i++);
|
||||
else
|
||||
__i++;
|
||||
acl_pthread_mutex_unlock(&__mutex);
|
||||
acl_myfree(ctx);
|
||||
}
|
||||
@ -169,7 +173,7 @@ static void test_thread_pool(void)
|
||||
int i;
|
||||
|
||||
acl_pthread_mutex_init(&__mutex, NULL);
|
||||
thr_pool = acl_thread_pool_create(10, 10);
|
||||
thr_pool = acl_thread_pool_create(100, 10);
|
||||
|
||||
for (i = 0; i < 1000000; i++) {
|
||||
RUN_CTX *ctx = (RUN_CTX*) acl_mymalloc(sizeof(RUN_CTX));
|
||||
@ -181,6 +185,7 @@ static void test_thread_pool(void)
|
||||
acl_pthread_pool_destroy(thr_pool);
|
||||
acl_pthread_mutex_destroy(&__mutex);
|
||||
acl_vstream_close(fp);
|
||||
printf("last i: %d\r\n", __i);
|
||||
}
|
||||
|
||||
int main(int argc acl_unused, char *argv[] acl_unused)
|
@ -86,7 +86,7 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
@ -107,7 +107,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
@ -128,7 +128,7 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;ACL_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
@ -149,7 +149,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;ACL_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
@ -168,7 +168,7 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\lib_acl\lib_acl_vc2010.vcxproj">
|
||||
<ProjectReference Include="..\..\..\lib_acl\lib_acl_vc2010.vcxproj">
|
||||
<Project>{b40213c2-507c-4c7f-a6e1-b850c9bdc27b}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
@ -179,4 +179,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
@ -19,7 +19,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\lib_acl\include"
|
||||
AdditionalIncludeDirectories="..\..\..\lib_acl\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
@ -68,7 +68,7 @@
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..\..\lib_acl\include"
|
||||
AdditionalIncludeDirectories="..\..\..\lib_acl\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
@ -117,7 +117,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\lib_acl\include"
|
||||
AdditionalIncludeDirectories="..\..\..\lib_acl\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;ACL_DLL"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
@ -166,7 +166,7 @@
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..\..\lib_acl\include"
|
||||
AdditionalIncludeDirectories="..\..\..\lib_acl\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;ACL_DLL"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
2
samples/thread/thread_pool3/Makefile
Normal file
2
samples/thread/thread_pool3/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
include ../Makefile.in
|
||||
PROG = thread_pool
|
62
samples/thread/thread_pool3/main.c
Normal file
62
samples/thread/thread_pool3/main.c
Normal file
@ -0,0 +1,62 @@
|
||||
#include "lib_acl.h"
|
||||
#include <assert.h>
|
||||
|
||||
static acl_pthread_mutex_t __mutex;
|
||||
static int __n = 0;
|
||||
static void run_thread(void *arg acl_unused)
|
||||
{
|
||||
acl_pthread_mutex_lock(&__mutex);
|
||||
__n++;
|
||||
acl_pthread_mutex_unlock(&__mutex);
|
||||
}
|
||||
|
||||
static void test_thread_pool(int nthreads, int timeout, int nloop)
|
||||
{
|
||||
acl_pthread_pool_t *thr_pool;
|
||||
int i;
|
||||
|
||||
acl_pthread_mutex_init(&__mutex, NULL);
|
||||
thr_pool = acl_thread_pool_create(nthreads, timeout);
|
||||
|
||||
for (i = 0; i < nloop; i++)
|
||||
acl_pthread_pool_add_one(thr_pool, run_thread, NULL);
|
||||
|
||||
acl_pthread_pool_destroy(thr_pool);
|
||||
acl_pthread_mutex_destroy(&__mutex);
|
||||
printf("at last n: %d\r\n", __n);
|
||||
}
|
||||
|
||||
static void usage(const char *procname)
|
||||
{
|
||||
printf("usage: %s -h[help]\r\n"
|
||||
" -t threads_count[default: 10]\r\n"
|
||||
" -n loop_count[default: 100000]\r\n", procname);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ch;
|
||||
int nthreads = 10, nloop = 100000, timeout = 10;
|
||||
|
||||
while ((ch = getopt(argc, argv, "ht:n:T:")) > 0) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
case 't':
|
||||
nthreads = atoi(optarg);
|
||||
break;
|
||||
case 'n':
|
||||
nloop = atoi(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
timeout = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
test_thread_pool(nthreads, timeout, nloop);
|
||||
return 0;
|
||||
}
|
3
samples/thread/thread_pool3/valgrind.sh
Normal file
3
samples/thread/thread_pool3/valgrind.sh
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
valgrind --tool=memcheck --leak-check=yes -v ./thread_pool -t 10 -n 10000
|
@ -190,8 +190,7 @@ int test_htable_rwlock(AUT_LINE *test_line, void *arg acl_unused)
|
||||
tp = acl_thread_pool_create(threads, thread_idle);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (acl_pthread_pool_add(tp, __htable_rwlock_fn, &__rwlock_ctx))
|
||||
acl_msg_fatal("acl_workq_add error(%s)", strerror(errno));
|
||||
acl_pthread_pool_add(tp, __htable_rwlock_fn, &__rwlock_ctx);
|
||||
}
|
||||
|
||||
sleep(2);
|
||||
|
Loading…
Reference in New Issue
Block a user