You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openharmonydocs/pthread_cond_test_002.cpp

142 lines
5.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "it_pthread_test.h" // 引入测试头文件
// 全局变量定义
static pthread_mutex_t g_pthreadMuxTest1; // 互斥锁
static pthread_cond_t g_pthrdCondTest1; // 条件变量
static unsigned int g_pthreadExit = 0; // 控制线程退出的标志
// 线程函数1模拟一个消费者
static void *PthreadF01(void *t)
{
int rc;
unsigned int count = 0;
const int testLoop = 2000; // 循环次数为2000
// 循环2000次进行条件变量等待和互斥锁操作
while (count < testLoop) {
// 加锁
rc = pthread_mutex_lock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 判断加锁是否成功失败则跳转到EXIT
// 等待条件变量,释放互斥锁并进入阻塞状态,直到条件变量通知
rc = pthread_cond_wait(&g_pthrdCondTest1, &g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
// 解锁
rc = pthread_mutex_unlock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
count++; // 增加计数器
}
// 设置退出标志
g_pthreadExit = 1;
EXIT:
return NULL; // 线程函数结束
}
// 线程函数2模拟一个生产者
static void *PthreadF02(void *t)
{
int rc;
// 当g_pthreadExit不为1时继续循环发送信号
while (g_pthreadExit != 1) {
// 加锁
rc = pthread_mutex_lock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 判断加锁是否成功失败则跳转到EXIT
// 发送信号,通知一个等待的线程
rc = pthread_cond_signal(&g_pthrdCondTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
// 解锁
rc = pthread_mutex_unlock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
}
EXIT:
pthread_exit(NULL); // 线程退出
}
// 测试用例
static unsigned int TestCase(void)
{
int i;
long t1 = 1; // 线程1的标识
long t2 = 2; // 线程2的标识
int rc;
pthread_t threads[3]; // 创建3个线程
pthread_attr_t attr; // 线程属性
const int loopNum = 2; // 循环创建和等待线程次数
g_pthreadExit = 0; // 初始化退出标志
g_testCount = 0; // 初始化测试计数器
// 初始化互斥锁和条件变量
pthread_mutex_init(&g_pthreadMuxTest1, NULL);
pthread_cond_init(&g_pthrdCondTest1, NULL);
// 创建线程1 (消费者)
rc = pthread_create(&threads[0], NULL, PthreadF01, (void *)t1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确认线程创建成功
// 创建线程2 (生产者)
rc = pthread_create(&threads[1], NULL, PthreadF02, (void *)t2);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确认线程创建成功
// 等待线程1和线程2执行完毕
for (i = 0; i < loopNum; i++) {
rc = pthread_join(threads[i], NULL);
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_cond_destroy(&g_pthrdCondTest1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确认销毁条件变量成功
return 0; // 返回0表示测试通过
}
// 测试入口函数
void ItTestPthreadCond002(void)
{
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_002", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION);
}