From 9958d730d9f81f679d99ec24883304c6839bb6a0 Mon Sep 17 00:00:00 2001 From: lucius Date: Mon, 1 Sep 2025 16:35:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=20ThreadMutex=20=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + README.md | 5 ++ build/Ndk_Android.mk | 28 ++++++++++++ build/Ndk_Application.mk | 4 ++ build/ndk_make.sh | 99 ++++++++++++++++++++++++++++++++++++++++ code/ThreadMutex.cpp | 53 +++++++++++++++++++++ code/ThreadMutex.h | 21 +++++++++ code/main.cpp | 47 +++++++++++++++++++ 8 files changed, 259 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 build/Ndk_Android.mk create mode 100644 build/Ndk_Application.mk create mode 100755 build/ndk_make.sh create mode 100644 code/ThreadMutex.cpp create mode 100644 code/ThreadMutex.h create mode 100644 code/main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..02e88ee --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/build/libs/ +/build/obj/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..b99b06b --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +V1.1.0 + +### 新增: + +实现`ThreadMutex`类 diff --git a/build/Ndk_Android.mk b/build/Ndk_Android.mk new file mode 100644 index 0000000..a85741b --- /dev/null +++ b/build/Ndk_Android.mk @@ -0,0 +1,28 @@ +# 设置当前模块的源文件路径 +LOCAL_PATH := $(call my-dir) + +# 清除几乎所有 LOCAL_XXX 变量,为定义新模块做准备 +include $(CLEAR_VARS) + +# 模块名称,这将决定输出文件的名字(例如生成 libmynative.so) +LOCAL_MODULE := myapp + +# 指定需要编译的源文件 +LOCAL_SRC_FILES := \ + ../code/ThreadMutex.cpp ../code/main.cpp + +# 指定头文件搜索路径 +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/../code/ + +# 编译C文件时的标志 +LOCAL_CFLAGS := -D__OS_ANDROID + +# 编译C++文件时的标志 +LOCAL_CPPFLAGS += -std=c++11 -android + +# 链接时依赖的系统库 +LOCAL_LDLIBS := -llog -lc + +# 指示构建系统将其编译为动态链接库 +include $(BUILD_EXECUTABLE) \ No newline at end of file diff --git a/build/Ndk_Application.mk b/build/Ndk_Application.mk new file mode 100644 index 0000000..3effe8f --- /dev/null +++ b/build/Ndk_Application.mk @@ -0,0 +1,4 @@ +APP_STL:=gnustl_static +APP_ABI:=armeabi-v7a +APP_PLATFORM:=android-23 +APP_BUILD_SCRIPT:=Ndk_Android.mk diff --git a/build/ndk_make.sh b/build/ndk_make.sh new file mode 100755 index 0000000..a22201f --- /dev/null +++ b/build/ndk_make.sh @@ -0,0 +1,99 @@ +#!/bin/bash + +source /opt/ndk/env/ndk_env.sh + +# 定义颜色 +RED="\033[0;31m" +GREEN="\033[0;32m" +YELLOW="\033[1;33m" +BLUE="\033[0;34m" +RESET="\033[0m" + +# 路径 +NDK_PROJECT_PATH=$(pwd) +APP_MK="./Ndk_Application.mk" +ANDROID_MK="./Ndk_Android.mk" +FIRMWARE_PATH="obj/local/armeabi-v7a/myapp" +DEVICE_DATA="/data/" +DEVICE_IP="" + +clean() { + echo -e "${YELLOW}Cleaning up...${RESET}" + ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=$APP_MK APP_BUILD_SCRIPT=$ANDROID_MK clean + echo -e "${YELLOW}Removing obj/ and libs/ directories...${RESET}" + rm -rf obj/ libs/ + sync + echo -e "${GREEN}Cleaned up.${RESET}" +} + +build_only() { + echo -e "${BLUE}Building myapp...${RESET}" + ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=$APP_MK APP_BUILD_SCRIPT=$ANDROID_MK + echo -e "${GREEN}Only build completed successfully.${RESET}" +} + +push_only() { + if [ -z "$DEVICE_IP" ]; then + echo -e "${RED}Error: No device IP provided. Use -p ${RESET}" + exit 1 + fi + echo -e "${BLUE}Connecting to device $DEVICE_IP...${RESET}" + adb connect $DEVICE_IP + if [ $? -ne 0 ]; then + echo -e "${RED}Failed to connect to device $DEVICE_IP${RESET}" + exit 1 + fi + + echo -e "${BLUE}Pushing myapp to $DEVICE_DATA...${RESET}" + adb -s $DEVICE_IP push $FIRMWARE_PATH $DEVICE_DATA + if [ $? -ne 0 ]; then + echo -e "${RED}Failed to push myapp to $DEVICE_DATA${RESET}" + exit 1 + fi + + echo -e "${GREEN}Push completed successfully.${RESET}" +} + +build_and_push() { + build_only + push_only +} + +show_help() { + echo -e "${YELLOW}Usage: $0 [options]${RESET}" + echo + echo "Options:" + echo -e " ${BLUE}-c${RESET} Clean project (remove obj/ and libs/)" + echo -e " ${BLUE}-p ${RESET} Push myapp to device with given IP" + echo -e " ${BLUE}-bp ${RESET} Build and push to device with given IP" + echo -e " ${BLUE}-h${RESET} Show this help message" + echo + echo -e "${YELLOW}Default:${RESET} If no options are given, only build the project." +} + +# 参数解析 +if [ $# -eq 0 ]; then + build_only + exit 0 +fi + +case "$1" in + -c) + clean + ;; + -p) + DEVICE_IP="$2" + push_only + ;; + -bp) + DEVICE_IP="$2" + build_and_push + ;; + -h) + show_help + ;; + *) + show_help + exit 1 + ;; +esac diff --git a/code/ThreadMutex.cpp b/code/ThreadMutex.cpp new file mode 100644 index 0000000..45d81aa --- /dev/null +++ b/code/ThreadMutex.cpp @@ -0,0 +1,53 @@ +#include "ThreadMutex.h" + +int ThreadMutex::XLockGetTestFlag(void) +{ + return mCurTestFlag_; +} + +bool ThreadMutex::XLockTryLock(int tInputWait10Ms, int tInputTestFlag) +{ + int tTempN; + + if (tInputWait10Ms <= 0) + { + while (1) + { + if (0 == pthread_mutex_trylock(&mMutex_)) + { + mCurTestFlag_ = tInputTestFlag; + return true; + } + usleep(1000 * 5); + } + } + else + { + for (tTempN = 0; tTempN < tInputWait10Ms; tTempN++) + { + if (0 == pthread_mutex_trylock(&mMutex_)) + { + mCurTestFlag_ = tInputTestFlag; + return true; + } + usleep(1000 * 5); + } + return false; + } +} + +void ThreadMutex::XLockUnLock(void) +{ + mCurTestFlag_ = -1; + pthread_mutex_unlock(&mMutex_); +} + +ThreadMutex::ThreadMutex(void) +{ + pthread_mutex_init(&mMutex_, NULL); +} + +ThreadMutex::~ThreadMutex() +{ + pthread_mutex_destroy(&mMutex_); +} diff --git a/code/ThreadMutex.h b/code/ThreadMutex.h new file mode 100644 index 0000000..2680226 --- /dev/null +++ b/code/ThreadMutex.h @@ -0,0 +1,21 @@ +#ifndef THREADMUTE_H +#define THREADMUTE_H + +#include +#include + +class ThreadMutex +{ +public: + int XLockGetTestFlag(void); + bool XLockTryLock(int tInputWait10Ms, int tInputTestFlag = -1); + void XLockUnLock(void); + ThreadMutex(void); + ~ThreadMutex(); + +private: + pthread_mutex_t mMutex_; + int mCurTestFlag_; +}; + +#endif \ No newline at end of file diff --git a/code/main.cpp b/code/main.cpp new file mode 100644 index 0000000..99d5acd --- /dev/null +++ b/code/main.cpp @@ -0,0 +1,47 @@ +#include "ThreadMutex.h" +#include + +ThreadMutex gThreadMutex; + +void *threadFunc(void *arg) +{ + int tTemID = *(int *)arg; + for (int tTempN = 0; tTempN < 3; ++tTempN) + { + if (gThreadMutex.XLockTryLock(100, tTemID)) + { + std::cout << "[Thread " << tTemID << "] got lock, iteration " << tTempN << std::endl; + usleep(1000 * 200); // 模拟操作,200ms + gThreadMutex.XLockUnLock(); + std::cout << "[Thread " << tTemID << "] released lock, iteration " << tTempN << std::endl; + } + else + { + std::cout << "[Thread " << tTemID << "] failed to get lock, iteration " << tTempN << std::endl; + } + usleep(1000 * 50); // 等待 50ms 再尝试下一轮 + } + return nullptr; +} + +int main(int argc, char **argv) +{ + const int tTemThreadNum = 3; + pthread_t threads[tTemThreadNum]; + int threadIds[tTemThreadNum] = {1, 2, 3}; + + /* 创建线程 */ + for (int tTempN = 0; tTempN < tTemThreadNum; ++tTempN) + { + pthread_create(&threads[tTempN], nullptr, threadFunc, &threadIds[tTempN]); + } + + /* 等待线程结束 */ + for (int tTempN = 0; tTempN < tTemThreadNum; ++tTempN) + { + pthread_join(threads[tTempN], nullptr); + } + + std::cout << "All threads finished." << std::endl; + return 0; +}