熊卓孜 7 months ago
commit 222949d5be

@ -29,66 +29,66 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "it_pthread_test.h" #include "it_pthread_test.h"
// 全局变量 // 全局变量
static volatile int g_count = 0; // 计数器,控制线程的执行 static volatile int g_count = 0; // 计数器,控制线程的执行
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; // 互斥锁,用于同步 static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; // 互斥锁,用于同步
static int g_testAtforkCount = 0; // 测试计数器,用于检查不同阶段 static int g_testAtforkCount = 0; // 测试计数器,用于检查不同阶段
static int g_testAtforkPrepare = 0; // 用于检查fork前的准备阶段 static int g_testAtforkPrepare = 0; // 用于检查fork前的准备阶段
static int g_testAtforkParent = 0; // 用于标记父进程执行的步骤 static int g_testAtforkParent = 0; // 用于标记父进程执行的步骤
static int g_testAtforkChild = 0; // 用于标记子进程执行的步骤 static int g_testAtforkChild = 0; // 用于标记子进程执行的步骤
static const int SLEEP_TIME = 2; // 睡眠时间,单位秒 static const int SLEEP_TIME = 2; // 睡眠时间,单位秒
// 准备函数fork之前执行 // 准备函数fork之前执行
static void Prepare() static void Prepare()
{ {
int err; int err;
ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); // 确保g_testAtforkCount为1 ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); // 确保g_testAtforkCount为1
err = pthread_mutex_lock(&g_lock); // 加锁 err = pthread_mutex_lock(&g_lock); // 加锁
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); // 确保加锁成功 ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); // 确保加锁成功
g_testAtforkPrepare++; // 标记准备阶段已执行 g_testAtforkPrepare++; // 标记准备阶段已执行
} }
// 父进程执行的函数 // 父进程执行的函数
static void Parent() static void Parent()
{ {
int err; int err;
ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); // 确保g_testAtforkCount为1 ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); // 确保g_testAtforkCount为1
err = pthread_mutex_unlock(&g_lock); // 解锁 err = pthread_mutex_unlock(&g_lock); // 解锁
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); // 确保解锁成功 ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); // 确保解锁成功
g_testAtforkParent++; // 标记父进程阶段已执行 g_testAtforkParent++; // 标记父进程阶段已执行
} }
// 子进程执行的函数 // 子进程执行的函数
static void child() static void child()
{ {
int err; int err;
ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); // 确保g_testAtforkCount为1 ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); // 确保g_testAtforkCount为1
err = pthread_mutex_unlock(&g_lock); // 解锁 err = pthread_mutex_unlock(&g_lock); // 解锁
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); // 确保解锁成功 ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); // 确保解锁成功
g_testAtforkChild++; // 标记子进程阶段已执行 g_testAtforkChild++; // 标记子进程阶段已执行
} }
// 线程执行的函数 // 线程执行的函数
static void *ThreadProc(void *arg) static void *ThreadProc(void *arg)
{ {
int err; int err;
// 当g_count小于5时线程继续执行 // 当g_count小于5时线程继续执行
while (g_count < 5) { // 5, 等待直到g_count == 5 while (g_count < 5) { // 5, 等待直到g_count == 5
err = pthread_mutex_lock(&g_lock); // 加锁 err = pthread_mutex_lock(&g_lock); // 加锁
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保加锁成功 ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保加锁成功
g_count++; // 增加计数 g_count++; // 增加计数
SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU
err = pthread_mutex_unlock(&g_lock); // 解锁 err = pthread_mutex_unlock(&g_lock); // 解锁
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保解锁成功 ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保解锁成功
SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU
} }
EXIT: EXIT:
return NULL; return NULL;
} }
// 测试pthread_atfork的函数 // 测试pthread_atfork的函数
static void *PthreadAtforkTest(void *arg) static void *PthreadAtforkTest(void *arg)
{ {
int err; int err;
@ -96,63 +96,63 @@ static void *PthreadAtforkTest(void *arg)
pthread_t tid; pthread_t tid;
int status = 0; int status = 0;
// 初始化全局变量 // 初始化全局变量
g_count = 0; g_count = 0;
g_testAtforkCount = 0; g_testAtforkCount = 0;
g_testAtforkPrepare = 0; g_testAtforkPrepare = 0;
g_testAtforkParent = 0; g_testAtforkParent = 0;
g_testAtforkChild = 0; g_testAtforkChild = 0;
// 创建新线程 // 创建新线程
err = pthread_create(&tid, NULL, ThreadProc, NULL); err = pthread_create(&tid, NULL, ThreadProc, NULL);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保线程创建成功 ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保线程创建成功
err = pthread_atfork(Prepare, Parent, child); // 注册fork前后要执行的函数 err = pthread_atfork(Prepare, Parent, child); // 注册fork前后要执行的函数
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保注册成功 ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保注册成功
g_testAtforkCount++; // 标记已执行测试的计数 g_testAtforkCount++; // 标记已执行测试的计数
SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU
// 创建子进程 // 创建子进程
pid = fork(); pid = fork();
ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 确保pid合理子进程的pid不会超过100000 ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 确保pid合理子进程的pid不会超过100000
ICUNIT_GOTO_EQUAL(g_testAtforkPrepare, 1, g_testAtforkPrepare, EXIT); // 确保准备阶段已执行 ICUNIT_GOTO_EQUAL(g_testAtforkPrepare, 1, g_testAtforkPrepare, EXIT); // 确保准备阶段已执行
// 子进程执行的代码 // 子进程执行的代码
if (pid == 0) { if (pid == 0) {
ICUNIT_GOTO_EQUAL(g_testAtforkChild, 1, g_testAtforkChild, EXIT); // 确保子进程阶段已执行 ICUNIT_GOTO_EQUAL(g_testAtforkChild, 1, g_testAtforkChild, EXIT); // 确保子进程阶段已执行
while (g_count < 5) { // 等待直到g_count == 5 while (g_count < 5) { // 等待直到g_count == 5
err = pthread_mutex_lock(&g_lock); // 加锁 err = pthread_mutex_lock(&g_lock); // 加锁
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保加锁成功 ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保加锁成功
g_count++; // 增加计数 g_count++; // 增加计数
SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU
err = pthread_mutex_unlock(&g_lock); // 解锁 err = pthread_mutex_unlock(&g_lock); // 解锁
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保解锁成功 ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保解锁成功
SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU
} }
exit(15); // 退出并设置状态为15 exit(15); // 退出并设置状态为15
} }
// 父进程的验证 // 父进程的验证
ICUNIT_GOTO_EQUAL(g_testAtforkParent, 1, g_testAtforkParent, EXIT_WAIT); ICUNIT_GOTO_EQUAL(g_testAtforkParent, 1, g_testAtforkParent, EXIT_WAIT);
err = pthread_join(tid, NULL); // 等待线程结束 err = pthread_join(tid, NULL); // 等待线程结束
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT_WAIT); ICUNIT_GOTO_EQUAL(err, 0, err, EXIT_WAIT);
// 父进程等待子进程结束并验证退出状态 // 父进程等待子进程结束并验证退出状态
err = waitpid(pid, &status, 0); err = waitpid(pid, &status, 0);
status = WEXITSTATUS(status); status = WEXITSTATUS(status);
ICUNIT_GOTO_EQUAL(err, pid, err, EXIT); // 确保waitpid成功 ICUNIT_GOTO_EQUAL(err, pid, err, EXIT); // 确保waitpid成功
ICUNIT_GOTO_EQUAL(status, 15, status, EXIT); // 确保子进程的退出状态为15 ICUNIT_GOTO_EQUAL(status, 15, status, EXIT); // 确保子进程的退出状态为15
EXIT: EXIT:
return NULL; return NULL;
EXIT_WAIT: EXIT_WAIT:
(void)waitpid(pid, &status, 0); // 等待子进程结束 (void)waitpid(pid, &status, 0); // 等待子进程结束
return NULL; return NULL;
} }
// 测试主程序 // 测试主程序
static int Testcase() static int Testcase()
{ {
int ret; int ret;
@ -161,28 +161,28 @@ static int Testcase()
pthread_attr_t a = { 0 }; pthread_attr_t a = { 0 };
struct sched_param param = { 0 }; struct sched_param param = { 0 };
// 获取当前线程的调度参数 // 获取当前线程的调度参数
ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, &param); ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, &param);
ICUNIT_ASSERT_EQUAL(ret, 0, -ret); ICUNIT_ASSERT_EQUAL(ret, 0, -ret);
curThreadPri = param.sched_priority; curThreadPri = param.sched_priority;
// 设置新的线程属性并创建新线程 // 设置新的线程属性并创建新线程
ret = pthread_attr_init(&a); ret = pthread_attr_init(&a);
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
param.sched_priority = curThreadPri + 2; // 提高线程优先级 param.sched_priority = curThreadPri + 2; // 提高线程优先级
pthread_attr_setschedparam(&a, &param); pthread_attr_setschedparam(&a, &param);
ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0); // 创建新线程 ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0); // 创建新线程
ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 等待新线程结束 // 等待新线程结束
ret = pthread_join(newPthread, NULL); ret = pthread_join(newPthread, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return 0; return 0;
} }
// 测试用例的入口函数 // 测试用例的入口函数
void ItTestPthreadAtfork001(void) void ItTestPthreadAtfork001(void)
{ {
TEST_ADD_CASE("IT_PTHREAD_ATFORK_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); TEST_ADD_CASE("IT_PTHREAD_ATFORK_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);

@ -38,13 +38,13 @@
extern int nanosleep(const struct timespec *req, struct timespec *rem); extern int nanosleep(const struct timespec *req, struct timespec *rem);
// 全局变量 // 全局变量
static pthread_mutex_t g_mux = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t g_mux = PTHREAD_MUTEX_INITIALIZER;
static volatile int g_testAtforkCount = 0; static volatile int g_testAtforkCount = 0;
static int g_testAtforkPrepare = 0; static int g_testAtforkPrepare = 0;
static int g_testAtforkParent = 0; static int g_testAtforkParent = 0;
// 函数原型 // 函数原型
static void *Doit(void *arg); static void *Doit(void *arg);
static void *Doit1(void *arg); static void *Doit1(void *arg);
static void Prepare(void); static void Prepare(void);
@ -53,69 +53,69 @@ static void *PthreadAtforkTest(void *arg);
static int Testcase(void); static int Testcase(void);
void ItTestPthreadAtfork002(void); void ItTestPthreadAtfork002(void);
// Doit 函数(线程 1 // Doit 函数(线程 1
static void *Doit(void *arg) static void *Doit(void *arg)
{ {
int err; int err;
struct timespec ts = { 2, 0 }; // 睡眠 2 秒 struct timespec ts = { 2, 0 }; // 睡眠 2 秒
// 确保全局变量 g_testAtforkCount 为 1 // 确保全局变量 g_testAtforkCount 为 1
if (g_testAtforkCount != 1) { if (g_testAtforkCount != 1) {
return NULL; return NULL;
} }
// 锁住互斥锁 // 锁住互斥锁
err = pthread_mutex_lock(&g_mux); err = pthread_mutex_lock(&g_mux);
if (err != 0) return NULL; if (err != 0) return NULL;
(void)nanosleep(&ts, NULL); // 睡眠 2 秒 (void)nanosleep(&ts, NULL); // 睡眠 2 秒
err = pthread_mutex_unlock(&g_mux); // 解锁互斥锁 err = pthread_mutex_unlock(&g_mux); // 解锁互斥锁
if (err != 0) return NULL; if (err != 0) return NULL;
return NULL; return NULL;
} }
// Doit1 函数(线程 2 - 子进程) // Doit1 函数(线程 2 - 子进程)
static void *Doit1(void *arg) static void *Doit1(void *arg)
{ {
int err; int err;
struct timespec ts = { 2, 0 }; // 睡眠 2 秒 struct timespec ts = { 2, 0 }; // 睡眠 2 秒
// 确保全局变量 g_testAtforkCount 为 1 // 确保全局变量 g_testAtforkCount 为 1
if (g_testAtforkCount != 1) { if (g_testAtforkCount != 1) {
return NULL; return NULL;
} }
// 锁住互斥锁 // 锁住互斥锁
err = pthread_mutex_lock(&g_mux); err = pthread_mutex_lock(&g_mux);
if (err != 0) return NULL; if (err != 0) return NULL;
(void)nanosleep(&ts, NULL); // 睡眠 2 秒 (void)nanosleep(&ts, NULL); // 睡眠 2 秒
err = pthread_mutex_unlock(&g_mux); // 解锁互斥锁 err = pthread_mutex_unlock(&g_mux); // 解锁互斥锁
if (err != 0) return NULL; if (err != 0) return NULL;
return NULL; return NULL;
} }
// Prepare 函数(在 fork 前调用) // Prepare 函数(在 fork 前调用)
static void Prepare(void) static void Prepare(void)
{ {
int err; int err;
err = pthread_mutex_unlock(&g_mux); // 在 fork 前解锁互斥锁 err = pthread_mutex_unlock(&g_mux); // 在 fork 前解锁互斥锁
if (err != 0) return; if (err != 0) return;
g_testAtforkPrepare++; // 增加 prepare 计数 g_testAtforkPrepare++; // 增加 prepare 计数
} }
// Parent 函数(在 fork 后父进程中调用) // Parent 函数(在 fork 后父进程中调用)
static void Parent(void) static void Parent(void)
{ {
int err = pthread_mutex_lock(&g_mux); // 在父进程中锁住互斥锁 int err = pthread_mutex_lock(&g_mux); // 在父进程中锁住互斥锁
if (err != 0) return; if (err != 0) return;
g_testAtforkParent++; // 增加父进程计数 g_testAtforkParent++; // 增加父进程计数
} }
// PthreadAtforkTest 函数(主测试函数) // PthreadAtforkTest 函数(主测试函数)
static void *PthreadAtforkTest(void *arg) static void *PthreadAtforkTest(void *arg)
{ {
int err, ret; int err, ret;
@ -128,45 +128,45 @@ static void *PthreadAtforkTest(void *arg)
g_testAtforkPrepare = 0; g_testAtforkPrepare = 0;
g_testAtforkParent = 0; g_testAtforkParent = 0;
// 注册 pthread_atfork 的回调函数 // 注册 pthread_atfork 的回调函数
err = pthread_atfork(Prepare, Parent, NULL); err = pthread_atfork(Prepare, Parent, NULL);
if (err != 0) return NULL; if (err != 0) return NULL;
g_testAtforkCount++; // 增加计数用于测试 g_testAtforkCount++; // 增加计数用于测试
// 创建一个线程执行 Doit 函数 // 创建一个线程执行 Doit 函数
err = pthread_create(&tid, NULL, Doit, NULL); err = pthread_create(&tid, NULL, Doit, NULL);
if (err != 0) return NULL; if (err != 0) return NULL;
nanosleep(&ts, NULL); // 睡眠 1 秒 nanosleep(&ts, NULL); // 睡眠 1 秒
pid = fork(); // 创建子进程 pid = fork(); // 创建子进程
// 检查 Prepare 函数是否被调用 // 检查 Prepare 函数是否被调用
if (g_testAtforkPrepare != 1) { if (g_testAtforkPrepare != 1) {
return NULL; return NULL;
} }
if (pid == 0) { if (pid == 0) {
Doit1(NULL); // 在子进程中执行 Doit1 函数 Doit1(NULL); // 在子进程中执行 Doit1 函数
exit(10); // 子进程退出,返回状态 10 exit(10); // 子进程退出,返回状态 10
} }
if (pid <= 0) { if (pid <= 0) {
return NULL; return NULL;
} }
// 检查 Parent 函数是否被调用 // 检查 Parent 函数是否被调用
if (g_testAtforkParent != 1) { if (g_testAtforkParent != 1) {
return NULL; return NULL;
} }
// 等待线程执行完毕 // 等待线程执行完毕
err = pthread_join(tid, NULL); err = pthread_join(tid, NULL);
if (err != 0) return NULL; if (err != 0) return NULL;
// 等待子进程结束 // 等待子进程结束
err = waitpid(pid, &status, 0); err = waitpid(pid, &status, 0);
status = WEXITSTATUS(status); // 获取子进程退出状态 status = WEXITSTATUS(status); // 获取子进程退出状态
if (err != pid || status != 10) { if (err != pid || status != 10) {
return NULL; return NULL;
} }
@ -174,7 +174,7 @@ static void *PthreadAtforkTest(void *arg)
return NULL; return NULL;
} }
// Testcase 函数(初始化线程调度参数并执行测试) // Testcase 函数(初始化线程调度参数并执行测试)
static int Testcase(void) static int Testcase(void)
{ {
int ret; int ret;
@ -183,33 +183,33 @@ static int Testcase(void)
pthread_attr_t a = { 0 }; pthread_attr_t a = { 0 };
struct sched_param param = { 0 }; struct sched_param param = { 0 };
// 获取当前线程的调度参数 // 获取当前线程的调度参数
ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, &param); ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, &param);
if (ret != 0) return ret; if (ret != 0) return ret;
curThreadPri = param.sched_priority; curThreadPri = param.sched_priority;
// 初始化线程属性 // 初始化线程属性
ret = pthread_attr_init(&a); ret = pthread_attr_init(&a);
if (ret != 0) return ret; if (ret != 0) return ret;
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
param.sched_priority = curThreadPri + 2; // 设置线程优先级为当前优先级 + 2 param.sched_priority = curThreadPri + 2; // 设置线程优先级为当前优先级 + 2
pthread_attr_setschedparam(&a, &param); pthread_attr_setschedparam(&a, &param);
// 创建新线程执行 PthreadAtforkTest 函数 // 创建新线程执行 PthreadAtforkTest 函数
ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0); ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0);
if (ret != 0) return ret; if (ret != 0) return ret;
// 等待新线程执行完毕 // 等待新线程执行完毕
ret = pthread_join(newPthread, NULL); ret = pthread_join(newPthread, NULL);
if (ret != 0) return ret; if (ret != 0) return ret;
return 0; return 0;
} }
// ItTestPthreadAtfork002 函数(测试用例入口) // ItTestPthreadAtfork002 函数(测试用例入口)
void ItTestPthreadAtfork002(void) void ItTestPthreadAtfork002(void)
{ {
TEST_ADD_CASE("IT_PTHREAD_ATFORK_002", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); TEST_ADD_CASE("IT_PTHREAD_ATFORK_002", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
} }

@ -29,109 +29,187 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <pthread.h> #include <pthread.h>
#include "ICUnit.h" // 假设你有这个头文件来处理测试相关的宏 #include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <time.h>
#include <sched.h>
extern int nanosleep(const struct timespec *req, struct timespec *rem);
// 全局变量
static pthread_mutex_t g_mux = PTHREAD_MUTEX_INITIALIZER;
static volatile int g_testAtforkCount = 0;
static int g_testAtforkPrepare = 0;
static int g_testAtforkParent = 0;
// 函数原型
static void *Doit(void *arg);
static void *Doit1(void *arg);
static void Prepare(void);
static void Parent(void);
static void *PthreadAtforkTest(void *arg);
static int Testcase(void);
void ItTestPthreadAtfork002(void);
// Doit 函数(线程 1
static void *Doit(void *arg)
{
int err;
struct timespec ts = { 2, 0 }; // 睡眠 2 秒
// 确保全局变量 g_testAtforkCount 为 1
if (g_testAtforkCount != 1) {
return NULL;
}
static pthread_mutex_t g_pthreadMuxTest1; // 定义互斥锁 // 锁住互斥锁
static pthread_cond_t g_pthdCondTest1; // 定义条件变量 err = pthread_mutex_lock(&g_mux);
if (err != 0) return NULL;
// 线程1的函数 (void)nanosleep(&ts, NULL); // 睡眠 2 秒
static void *PthreadF01(void *t) err = pthread_mutex_unlock(&g_mux); // 解锁互斥锁
{ if (err != 0) return NULL;
int rc;
// 锁住互斥锁 return NULL;
rc = pthread_mutex_lock(&g_pthreadMuxTest1); }
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
// Doit1 函数(线程 2 - 子进程)
static void *Doit1(void *arg)
{
int err;
struct timespec ts = { 2, 0 }; // 睡眠 2 秒
g_testCount++; // g_testCount加1 // 确保全局变量 g_testAtforkCount 为 1
LosTaskDelay(100); // 延时100ms if (g_testAtforkCount != 1) {
ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 断言g_testCount应为2 return NULL;
g_testCount++; // g_testCount再加1 }
// 等待条件变量,释放互斥锁 // 锁住互斥锁
rc = pthread_cond_wait(&g_pthdCondTest1, &g_pthreadMuxTest1); err = pthread_mutex_lock(&g_mux);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); if (err != 0) return NULL;
ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 断言g_testCount应为5 (void)nanosleep(&ts, NULL); // 睡眠 2 秒
rc = pthread_mutex_unlock(&g_pthreadMuxTest1); // 解锁互斥锁 err = pthread_mutex_unlock(&g_mux); // 解锁互斥锁
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); if (err != 0) return NULL;
EXIT:
return NULL; return NULL;
} }
// 线程2的函数 // Prepare 函数(在 fork 前调用)
static void *PthreadF02(void *t) static void Prepare(void)
{
int err;
err = pthread_mutex_unlock(&g_mux); // 在 fork 前解锁互斥锁
if (err != 0) return;
g_testAtforkPrepare++; // 增加 prepare 计数
}
// Parent 函数(在 fork 后父进程中调用)
static void Parent(void)
{
int err = pthread_mutex_lock(&g_mux); // 在父进程中锁住互斥锁
if (err != 0) return;
g_testAtforkParent++; // 增加父进程计数
}
// PthreadAtforkTest 函数(主测试函数)
static void *PthreadAtforkTest(void *arg)
{ {
int rc; int err, ret;
int pid;
int status = 0;
struct timespec ts = { 1, 0 };
pthread_t tid;
ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT); // 断言g_testCount应为1 g_testAtforkCount = 0;
g_testCount++; // g_testCount加1 g_testAtforkPrepare = 0;
g_testAtforkParent = 0;
// 锁住互斥锁 // 注册 pthread_atfork 的回调函数
rc = pthread_mutex_lock(&g_pthreadMuxTest1); err = pthread_atfork(Prepare, Parent, NULL);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); if (err != 0) return NULL;
ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 断言g_testCount应为3 g_testAtforkCount++; // 增加计数用于测试
g_testCount++; // g_testCount再加1
// 发送信号唤醒线程1 // 创建一个线程执行 Doit 函数
rc = pthread_cond_signal(&g_pthdCondTest1); err = pthread_create(&tid, NULL, Doit, NULL);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); if (err != 0) return NULL;
ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 断言g_testCount应为4 nanosleep(&ts, NULL); // 睡眠 1 秒
g_testCount++; // g_testCount再加1 pid = fork(); // 创建子进程
// 解锁互斥锁 // 检查 Prepare 函数是否被调用
rc = pthread_mutex_unlock(&g_pthreadMuxTest1); if (g_testAtforkPrepare != 1) {
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); return NULL;
}
if (pid == 0) {
Doit1(NULL); // 在子进程中执行 Doit1 函数
exit(10); // 子进程退出,返回状态 10
}
if (pid <= 0) {
return NULL;
}
// 检查 Parent 函数是否被调用
if (g_testAtforkParent != 1) {
return NULL;
}
// 等待线程执行完毕
err = pthread_join(tid, NULL);
if (err != 0) return NULL;
LosTaskDelay(2); // 延时2ms控制时序 // 等待子进程结束
err = waitpid(pid, &status, 0);
status = WEXITSTATUS(status); // 获取子进程退出状态
if (err != pid || status != 10) {
return NULL;
}
EXIT: return NULL;
pthread_exit(NULL);
} }
// 测试用例 // Testcase 函数(初始化线程调度参数并执行测试)
static unsigned int TestCase(void) static int Testcase(void)
{ {
int rc; int ret;
pthread_t threads[2]; // 需要2个线程来进行测试 pthread_t newPthread;
const int loopNum = 2; // 循环次数 int curThreadPri, curThreadPolicy;
pthread_attr_t a = { 0 };
g_testCount = 0; struct sched_param param = { 0 };
pthread_mutex_init(&g_pthreadMuxTest1, NULL); // 初始化互斥锁
pthread_cond_init(&g_pthdCondTest1, NULL); // 初始化条件变量 // 获取当前线程的调度参数
ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, &param);
// 创建线程1 if (ret != 0) return ret;
rc = pthread_create(&threads[0], NULL, PthreadF01, NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
// 创建线程2
rc = pthread_create(&threads[1], NULL, PthreadF02, NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
// 等待线程结束
for (int i = 0; i < loopNum; i++) {
rc = pthread_join(threads[i], NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
}
// 销毁线程属性 curThreadPri = param.sched_priority;
rc = pthread_attr_destroy(NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
// 销毁互斥锁和条件变量 // 初始化线程属性
rc = pthread_mutex_destroy(&g_pthreadMuxTest1); ret = pthread_attr_init(&a);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); if (ret != 0) return ret;
rc = pthread_cond_destroy(&g_pthdCondTest1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
param.sched_priority = curThreadPri + 2; // 设置线程优先级为当前优先级 + 2
pthread_attr_setschedparam(&a, &param);
// 创建新线程执行 PthreadAtforkTest 函数
ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0);
if (ret != 0) return ret;
// 等待新线程执行完毕
ret = pthread_join(newPthread, NULL);
if (ret != 0) return ret;
return 0; return 0;
} }
// 测试用例入口函数 // ItTestPthreadAtfork002 函数(测试用例入口)
void ItTestPthreadCond001(void) void ItTestPthreadAtfork002(void)
{ {
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_001", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); TEST_ADD_CASE("IT_PTHREAD_ATFORK_002", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
} }//超级大傻逼

@ -17,7 +17,7 @@
* permission. * permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * "AS IS" AND ANY EXPRESS AND IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
@ -28,92 +28,108 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "it_pthread_test.h" #include "it_pthread_test.h"
static pthread_mutex_t g_pthreadMuxTest1; // 全局变量声明
static pthread_cond_t g_pthrdCondTest1; static pthread_mutex_t g_pthreadMuxTest1; // 互斥锁
static unsigned int g_pthreadExit = 0; static pthread_cond_t g_pthrdCondTest1; // 条件变量
static unsigned int g_pthreadExit = 0; // 用于控制线程退出的标志
// 线程1的执行函数等待条件变量
static void *PthreadF01(void *t) static void *PthreadF01(void *t)
{ {
int rc; int rc;
unsigned int count = 0; unsigned int count = 0;
const int testLoop = 2000; const int testLoop = 2000; // 设置循环次数为2000次
// 循环等待条件变量并加锁互斥锁
while (count < testLoop) { while (count < testLoop) {
rc = pthread_mutex_lock(&g_pthreadMuxTest1); rc = pthread_mutex_lock(&g_pthreadMuxTest1); // 加锁互斥锁
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查加锁是否成功
rc = pthread_cond_wait(&g_pthrdCondTest1, &g_pthreadMuxTest1); rc = pthread_cond_wait(&g_pthrdCondTest1, &g_pthreadMuxTest1); // 等待条件变量
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查等待是否成功
rc = pthread_mutex_unlock(&g_pthreadMuxTest1); rc = pthread_mutex_unlock(&g_pthreadMuxTest1); // 解锁互斥锁
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查解锁是否成功
count++;
count++; // 增加计数
} }
g_pthreadExit = 1; g_pthreadExit = 1; // 设置退出标志
EXIT: EXIT:
return NULL; return NULL; // 返回空指针表示线程结束
} }
// 线程2的执行函数信号条件变量
static void *PthreadF02(void *t) static void *PthreadF02(void *t)
{ {
int i; int i;
int rc; int rc;
// 线程2循环发送信号唤醒等待中的线程1
while (g_pthreadExit != 1) { while (g_pthreadExit != 1) {
rc = pthread_mutex_lock(&g_pthreadMuxTest1); rc = pthread_mutex_lock(&g_pthreadMuxTest1); // 加锁互斥锁
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查加锁是否成功
rc = pthread_cond_signal(&g_pthrdCondTest1); rc = pthread_cond_signal(&g_pthrdCondTest1); // 发送条件变量信号
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查发送信号是否成功
rc = pthread_mutex_unlock(&g_pthreadMuxTest1); rc = pthread_mutex_unlock(&g_pthreadMuxTest1); // 解锁互斥锁
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查解锁是否成功
} }
EXIT: EXIT:
pthread_exit(NULL); pthread_exit(NULL); // 退出线程
} }
// 测试用例函数
static unsigned int TestCase(void) static unsigned int TestCase(void)
{ {
int i; int i;
long t1 = 1; long t1 = 1;
long t2 = 2; long t2 = 2;
int rc; int rc;
pthread_t threads[3]; pthread_t threads[3]; // 定义3个线程
pthread_attr_t attr; pthread_attr_t attr; // 线程属性
const int loopNum = 2; const int loopNum = 2; // 设置测试循环次数为2
g_pthreadExit = 0; // 初始化全局变量
g_testCount = 0; g_pthreadExit = 0; // 设置退出标志
pthread_mutex_init(&g_pthreadMuxTest1, NULL); g_testCount = 0; // 初始化测试计数
pthread_cond_init(&g_pthrdCondTest1, NULL); pthread_mutex_init(&g_pthreadMuxTest1, NULL); // 初始化互斥锁
pthread_cond_init(&g_pthrdCondTest1, NULL); // 初始化条件变量
// 创建线程1执行PthreadF01函数
rc = pthread_create(&threads[0], NULL, PthreadF01, (void *)t1); rc = pthread_create(&threads[0], NULL, PthreadF01, (void *)t1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确保线程创建成功
// 创建线程2执行PthreadF02函数
rc = pthread_create(&threads[1], NULL, PthreadF02, (void *)t2); rc = pthread_create(&threads[1], NULL, PthreadF02, (void *)t2);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确保线程创建成功
// 等待两个线程完成
for (i = 0; i < loopNum; i++) { for (i = 0; i < loopNum; i++) {
rc = pthread_join(threads[i], NULL); rc = pthread_join(threads[i], NULL); // 等待线程结束
ICUNIT_ASSERT_EQUAL(rc, 0, rc); ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确保线程结束正常
} }
rc = pthread_attr_destroy(&attr); // 销毁线程属性,互斥锁和条件变量
ICUNIT_ASSERT_EQUAL(rc, 0, rc); rc = pthread_attr_destroy(&attr); // 销毁线程属性
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 检查销毁是否成功
rc = pthread_mutex_destroy(&g_pthreadMuxTest1); // 销毁互斥锁
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 检查销毁是否成功
rc = pthread_mutex_destroy(&g_pthreadMuxTest1); rc = pthread_cond_destroy(&g_pthrdCondTest1); // 销毁条件变量
ICUNIT_ASSERT_EQUAL(rc, 0, rc); ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 检查销毁是否成功
rc = pthread_cond_destroy(&g_pthrdCondTest1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
return 0; return 0; // 测试用例成功结束
} }
// 测试函数入口
void ItTestPthreadCond002(void) void ItTestPthreadCond002(void)
{ {
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_002", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_002", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); // 添加测试用例
} }

@ -27,36 +27,46 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */#include "it_pthread_test.h"
#include "it_pthread_test.h"
static pthread_cond_t g_pthread_cond; // 全局变量,用于线程同步
static pthread_mutex_t g_pthread_mutex; static pthread_cond_t g_pthread_cond; // 条件变量
#define TEST_THREAD_COUNT 5 static pthread_mutex_t g_pthread_mutex; // 互斥锁
#define TEST_THREAD_COUNT 5 // 定义测试线程数量为5
// 线程函数,用于测试条件变量的超时等待
static void *pthread_cond_func001(void *arg) static void *pthread_cond_func001(void *arg)
{ {
int ret; int ret;
struct timespec ts; struct timespec ts;
// 增加全局变量 g_testCount 的计数
g_testCount++; g_testCount++;
// 加锁互斥锁
ret = pthread_mutex_lock(&g_pthread_mutex); ret = pthread_mutex_lock(&g_pthread_mutex);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); // 确保锁定成功
// 获取当前时间,并设置一个超时时间 (60秒后)
clock_gettime(CLOCK_REALTIME, &ts); clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 60; /* 60: wait 1 minute */ ts.tv_sec += 60; /* 60: wait 1 minute */
// 使用条件变量进行超时等待
ret = pthread_cond_timedwait(&g_pthread_cond, &g_pthread_mutex, &ts); ret = pthread_cond_timedwait(&g_pthread_cond, &g_pthread_mutex, &ts);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); // 确保条件变量等待成功
// 解锁互斥锁
ret = pthread_mutex_unlock(&g_pthread_mutex); ret = pthread_mutex_unlock(&g_pthread_mutex);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 增加全局变量 g_testCount 的计数
g_testCount++; g_testCount++;
EXIT: EXIT:
return NULL; return NULL; // 线程结束
} }
// 测试线程的创建及条件变量广播
static VOID *pthread_f06(void *argument) static VOID *pthread_f06(void *argument)
{ {
int policy; int policy;
@ -64,51 +74,66 @@ static VOID *pthread_f06(void *argument)
int i; int i;
pthread_attr_t attr; pthread_attr_t attr;
struct sched_param schedParam = { 0 }; struct sched_param schedParam = { 0 };
pthread_t thread[TEST_THREAD_COUNT]; pthread_t thread[TEST_THREAD_COUNT]; // 线程数组存放5个线程
// 初始化 g_testCount
g_testCount = 0; g_testCount = 0;
// 初始化线程属性
ret = pthread_attr_init(&attr); ret = pthread_attr_init(&attr);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 获取当前线程的调度参数(调度策略和优先级)
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam); ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 将当前线程优先级减一
schedParam.sched_priority -= 1; schedParam.sched_priority -= 1;
ret = pthread_attr_setschedparam(&attr, &schedParam); ret = pthread_attr_setschedparam(&attr, &schedParam);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 设置线程调度策略为显式调度
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 创建5个线程
for (i = 0; i < TEST_THREAD_COUNT; i++) { for (i = 0; i < TEST_THREAD_COUNT; i++) {
ret = pthread_create(&thread[i], &attr, pthread_cond_func001, NULL); ret = pthread_create(&thread[i], &attr, pthread_cond_func001, NULL);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); // 确保线程创建成功
} }
// 等待1秒钟保证线程已启动
sleep(1); sleep(1);
// 验证全局计数器 g_testCount应该为5
ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */ ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */
// 加锁互斥锁
ret = pthread_mutex_lock(&g_pthread_mutex); ret = pthread_mutex_lock(&g_pthread_mutex);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 向所有等待的线程发送条件变量广播
ret = pthread_cond_broadcast(&g_pthread_cond); ret = pthread_cond_broadcast(&g_pthread_cond);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 解锁互斥锁
ret = pthread_mutex_unlock(&g_pthread_mutex); ret = pthread_mutex_unlock(&g_pthread_mutex);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 等待所有线程执行完毕
for (i = 0; i < TEST_THREAD_COUNT; i++) { for (i = 0; i < TEST_THREAD_COUNT; i++) {
ret = pthread_join(thread[i], NULL); ret = pthread_join(thread[i], NULL);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); // 确保所有线程都成功结束
} }
// 验证全局计数器 g_testCount应该为10
ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); /* 10: Twice per thread */ ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); /* 10: Twice per thread */
EXIT: EXIT:
return NULL; return NULL; // 线程结束
} }
// 测试用例函数
static int TestCase(void) static int TestCase(void)
{ {
int policy; int policy;
@ -117,35 +142,45 @@ static int TestCase(void)
struct sched_param schedParam = { 0 }; struct sched_param schedParam = { 0 };
int ret; int ret;
// 初始化全局互斥锁
ret = pthread_mutex_init(&g_pthread_mutex, NULL); ret = pthread_mutex_init(&g_pthread_mutex, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 初始化全局条件变量
ret = pthread_cond_init(&g_pthread_cond, NULL); ret = pthread_cond_init(&g_pthread_cond, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 初始化线程属性
ret = pthread_attr_init(&attr); ret = pthread_attr_init(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 获取当前线程的调度参数
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam); ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 将当前线程优先级减一
schedParam.sched_priority -= 1; schedParam.sched_priority -= 1;
ret = pthread_attr_setschedparam(&attr, &schedParam); ret = pthread_attr_setschedparam(&attr, &schedParam);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 设置线程调度策略为显式调度
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 创建新线程执行 pthread_f06 函数
ret = pthread_create(&newTh, &attr, pthread_f06, NULL); ret = pthread_create(&newTh, &attr, pthread_f06, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 等待新线程执行完毕
ret = pthread_join(newTh, NULL); ret = pthread_join(newTh, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return 0; return 0; // 测试用例结束
} }
// 添加测试用例到测试框架
void ItTestPthreadCond003(void) void ItTestPthreadCond003(void)
{ {
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_003", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_003", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION);
} }

@ -27,117 +27,75 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */#include <pthread.h>
#include "it_pthread_test.h" #include "ICUnit.h" // 假设你有这个头文件来处理测试相关的宏
static pthread_cond_t g_pthread_cond;
static pthread_mutex_t g_pthread_mutex;
#define TEST_THREAD_COUNT 5
static void *pthread_cond_func002(void *arg) static pthread_mutex_t g_pthreadMuxTest1; // 互斥锁
{ static pthread_cond_t g_pthdCondTest1; // 条件变量
int ret; static int g_testCount = 0; // 测试计数
struct timespec ts;
g_testCount++; // 线程函数
static void *PthreadFunc(void *t)
{
int rc;
ret = pthread_mutex_lock(&g_pthread_mutex); // 线程1执行一系列的操作
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); rc = pthread_mutex_lock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
clock_gettime(CLOCK_REALTIME, &ts); g_testCount++; // g_testCount加1
ts.tv_sec += 2; /* 2: wait 2 seconds */ LosTaskDelay(100); // 延时100ms
ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 断言g_testCount为2
g_testCount++; // g_testCount再加1
ret = pthread_cond_timedwait(&g_pthread_cond, &g_pthread_mutex, &ts); // 等待条件变量,释放互斥锁
ICUNIT_GOTO_EQUAL(ret, ETIMEDOUT, ret, EXIT); rc = pthread_cond_wait(&g_pthdCondTest1, &g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
ret = pthread_mutex_unlock(&g_pthread_mutex); ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 断言g_testCount为5
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); rc = pthread_mutex_unlock(&g_pthreadMuxTest1); // 解锁互斥锁
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
g_testCount++;
EXIT: EXIT:
return NULL; return NULL;
} }
static VOID *pthread_f07(void *argument) // 测试用例
static unsigned int TestCase(void)
{ {
int policy; int rc;
int ret; pthread_t threads[2]; // 需要2个线程来进行测试
int i;
pthread_attr_t attr;
struct sched_param schedParam = { 0 };
pthread_t thread[TEST_THREAD_COUNT];
g_testCount = 0; g_testCount = 0;
pthread_mutex_init(&g_pthreadMuxTest1, NULL); // 初始化互斥锁
pthread_cond_init(&g_pthdCondTest1, NULL); // 初始化条件变量
ret = pthread_attr_init(&attr); // 创建线程1执行 PthreadFunc
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); rc = pthread_create(&threads[0], NULL, PthreadFunc, NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
schedParam.sched_priority -= 1;
ret = pthread_attr_setschedparam(&attr, &schedParam);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
for (i = 0; i < TEST_THREAD_COUNT; i++) {
ret = pthread_create(&thread[i], &attr, pthread_cond_func002, NULL);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
}
sleep(1);
ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */ // 创建线程2执行 PthreadFunc
rc = pthread_create(&threads[1], NULL, PthreadFunc, NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
for (i = 0; i < TEST_THREAD_COUNT; i++) { // 等待线程结束
ret = pthread_join(thread[i], NULL); for (int i = 0; i < 2; i++) {
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); rc = pthread_join(threads[i], NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
} }
ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); /* 10: Twice per thread */ // 销毁互斥锁和条件变量
rc = pthread_mutex_destroy(&g_pthreadMuxTest1);
EXIT: ICUNIT_ASSERT_EQUAL(rc, 0, rc);
return NULL; rc = pthread_cond_destroy(&g_pthdCondTest1);
} ICUNIT_ASSERT_EQUAL(rc, 0, rc);
static int TestCase(void)
{
int policy;
pthread_attr_t attr;
pthread_t newTh;
struct sched_param schedParam = { 0 };
int ret;
ret = pthread_mutex_init(&g_pthread_mutex, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_cond_init(&g_pthread_cond, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_attr_init(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
schedParam.sched_priority -= 1;
ret = pthread_attr_setschedparam(&attr, &schedParam);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_create(&newTh, &attr, pthread_f07, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_join(newTh, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return 0; return 0;
} }
void ItTestPthreadCond004(void) // 测试用例入口函数
void ItTestPthreadCond001(void)
{ {
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_004", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_001", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION);
} }

Loading…
Cancel
Save