优化了线程池的性能

通过给线程池中的每一个线程一个独立的线程条件变量(之前是用同一个),大大减少了线程池在任务调度时的竞争问题
This commit is contained in:
zsxxsz 2014-01-19 23:59:13 +08:00
parent 99f2645bda
commit a3b2e1f6d1
41 changed files with 2293 additions and 562 deletions

View File

@ -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 编译环境

View File

@ -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 使

View File

@ -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)

View File

@ -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 */

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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();

View File

@ -0,0 +1,2 @@
PROG = mmap_test
include ../Makefile.in

View 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;
}

View File

@ -0,0 +1,8 @@
// stdafx.cpp : 只包括标准包含文件的源文件
// xml.pch 将成为预编译头
// stdafx.obj 将包含预编译类型信息
#include "stdafx.h"
// TODO: 在 STDAFX.H 中
//引用任何所需的附加头文件,而不是在此文件中引用

View 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"

View File

@ -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)

View File

@ -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
View File

@ -0,0 +1,2 @@
include ../Makefile_cpp.in
PROG = json

124
samples/json3/main.cpp Normal file
View 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;
}

View File

@ -0,0 +1,3 @@
#!/bin/sh
valgrind --tool=memcheck --leak-check=yes -v ./json -b -m 10

View File

@ -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

View File

@ -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

View File

@ -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
View 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)
###########################################################

View 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)
###########################################################

View File

@ -0,0 +1,2 @@
include ../Makefile.in
PROG = thread

View File

@ -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>

View File

@ -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"

View File

@ -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);
}

View File

@ -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)

View File

@ -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>

View File

@ -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"

View File

@ -0,0 +1,2 @@
include ../Makefile.in
PROG = thread_pool

View 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;
}

View File

@ -0,0 +1,3 @@
#!/bin/sh
valgrind --tool=memcheck --leak-check=yes -v ./thread_pool -t 10 -n 10000

View File

@ -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);