新增:实现 ThreadMutex 类
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/build/libs/
|
||||||
|
/build/obj/
|
||||||
28
build/Ndk_Android.mk
Normal file
28
build/Ndk_Android.mk
Normal file
@ -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)
|
||||||
4
build/Ndk_Application.mk
Normal file
4
build/Ndk_Application.mk
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
APP_STL:=gnustl_static
|
||||||
|
APP_ABI:=armeabi-v7a
|
||||||
|
APP_PLATFORM:=android-23
|
||||||
|
APP_BUILD_SCRIPT:=Ndk_Android.mk
|
||||||
99
build/ndk_make.sh
Executable file
99
build/ndk_make.sh
Executable file
@ -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 <IP>${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 <IP>${RESET} Push myapp to device with given IP"
|
||||||
|
echo -e " ${BLUE}-bp <IP>${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
|
||||||
53
code/ThreadMutex.cpp
Normal file
53
code/ThreadMutex.cpp
Normal file
@ -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_);
|
||||||
|
}
|
||||||
21
code/ThreadMutex.h
Normal file
21
code/ThreadMutex.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef THREADMUTE_H
|
||||||
|
#define THREADMUTE_H
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
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
|
||||||
47
code/main.cpp
Normal file
47
code/main.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#include "ThreadMutex.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user