内容参考
ThreadX学习(3)——互斥锁_tx_mutex_create-CSDN博客
在此基础上添加一些实现代码。
1.tx_mutex_create
TX_MUTEX my_mutex; //先定义再创建
UINT tx_mutex_create( TX_MUTEX *mutex_ptr,
CHAR *name_ptr,
UINT inherit)
这个函数是创建互斥锁,创建互斥锁和创建线程一样要在tx_application_define中定义。
第一个参数是互斥控制块 Mutex Control Block (MCB)的指针
第二个参数是互斥锁的名字
第三个参数是是否允许互斥锁开启优先级继承
VOID tx_application_define(void *first_unused_memory)
{
UINT ret =tx_mutex_create(&mutex_0, "Mutex 0", TX_NO_INHERIT);
if (ret == TX_SUCCESS) {
// 互斥锁创建成功
char msg[] = "Mutex created successfully!\n";
HAL_UART_Transmit(&huart1, (uint8_t *)msg, strlen(msg), HAL_MAX_DELAY);
} else {
// 互斥锁创建失败
char error_msg[] = "Mutex creation failed!\n";
HAL_UART_Transmit(&huart1, (uint8_t *)error_msg, strlen(error_msg), HAL_MAX_DELAY);
}
/* Create the main thread. */
tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
thread_0_stack, DEMO_STACK_SIZE,
1, 1, 10, TX_AUTO_START);
tx_thread_create(&thread_1, "Thread 1", thread_1_entry, 0,
thread_1_stack, DEMO_STACK_SIZE,
2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
}
通过打印结果第一行可以看到,互斥锁已经成功创建。
2.tx_mutex_delete
UINT tx_mutex_delete(TX_MUTEX *mutex_ptr)
删除互斥锁不能和创建互斥锁一样在tx_applicaton_define里创建,要在线程逻辑内部创建。否则会报0x13,10进制19,错误意味无效的服务调用。
下面示例代码表示在线程1中删除了创建好的互斥锁,最终结果显示最后一行串口打印为0,表示删除成功。
当一个互斥锁被删除时,所有因为等待该锁而挂起的线程都会被恢复(放到就绪列表中)。这些线程都将从tx_mutex_get的调用中接收一个TX_DELETED返回状态。
void thread_0_entry(ULONG thread_input)
//线程,串口发送数据
{
TX_THREAD *thread_ptr;
CHAR *name_ptr;
UINT state;
ULONG run_count;
UINT priority;
UINT preemption_threshold;
ULONG time_slice;
UINT suspension_count;
TX_THREAD *next_thread;
TX_THREAD *previous_thread;
// 缓冲区用于格式化输出字符串
char buffer1[256];
// 获取当前线程的指针
thread_ptr = tx_thread_identify();
// 获取当前线程信息
tx_thread_info_get(thread_ptr, &name_ptr, &state, &run_count, &priority, &preemption_threshold,
&time_slice, &next_thread, &previous_thread);
// 格式化线程信息为字符串
snprintf(buffer1, sizeof(buffer1),
"Thread Name: %s\nState: %u\nRun Count: %lu\nPriority: %u\nPreemption Threshold: %u\nTime Slice: %lu\nSuspension Count: %u\n",
name_ptr, state, run_count, priority, preemption_threshold, time_slice, suspension_count);
// 通过UART发送线程信息
HAL_UART_Transmit(&huart1, (uint8_t *)buffer1, strlen(buffer1), HAL_MAX_DELAY);
UINT bb=tx_thread_time_slice_change(&thread_0,20,&time_slice);
tx_thread_info_get(thread_ptr, &name_ptr, &state, &run_count, &priority, &preemption_threshold,
&time_slice, &next_thread, &previous_thread);
// 格式化线程信息为字符串
snprintf(buffer1, sizeof(buffer1),
"Thread Name: %s\nState: %u\nRun Count: %lu\nPriority: %u\nPreemption Threshold: %u\nTime Slice: %lu\nSuspension Count: %u\n",
name_ptr, state, run_count, priority, preemption_threshold, time_slice, suspension_count);
// 通过UART发送线程信息
HAL_UART_Transmit(&huart1, (uint8_t *)buffer1, strlen(buffer1), HAL_MAX_DELAY);
}
void thread_1_entry(ULONG thread_input)
//线程1,控制led,只让他亮5s
{
char cc[]="线程2\n";
HAL_UART_Transmit(&huart1, (uint8_t *)cc, strlen(cc), HAL_MAX_DELAY);
UINT status = tx_mutex_delete(&mutex_0);
char buffer[256];
snprintf(buffer, sizeof(buffer),"%u\n",status);
HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
}
3.tx_mutex_get
UINT _tx_mutex_get(TX_MUTEX *mutex_ptr,
ULONG wait_option)
获取互斥锁,这个函数一般写在线程内部,让线程获取互斥锁的所有权。
在线程1中调用互斥锁获取函数后,调用互斥锁信息函数,得到互斥锁目前的信息,可以看到串口打印结果中,互斥锁的tx_mutex_ownership_count加1。
void thread_1_entry(ULONG thread_input)
//线程1,控制led,只让他亮5s
{
TX_MUTEX *mutex_ptr=&mutex_0;
CHAR *name;
ULONG count;
TX_THREAD *owner;
TX_THREAD *first_suspended;
ULONG suspended_count;
TX_MUTEX *next_mute;
char cc[]="线程2\n";
HAL_UART_Transmit(&huart1, (uint8_t *)cc, strlen(cc), HAL_MAX_DELAY);
UINT status = tx_mutex_get(&mutex_0,TX_WAIT_FOREVER);
char buffer[256];
snprintf(buffer, sizeof(buffer),"%u\n",status);
HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
char buffer1[256];
UINT aa = tx_mutex_info_get(mutex_ptr, &name, &count, &owner, &first_suspended, &suspended_count, &next_mute);
snprintf(buffer1, sizeof(buffer1), "Name: %s, Count: %lu, Owner: %p, First Suspended: %p, Suspended Count: %lu, Next Mutex: %p\n",
name, count, owner, first_suspended, suspended_count, next_mute);
HAL_UART_Transmit(&huart1, (uint8_t *)buffer1, strlen(buffer1), HAL_MAX_DELAY);
}
4.tx_mutex_info_get
UINT tx_mutex_info_get(TX_MUTEX *mutex_ptr,
CHAR **name,
ULONG *count,
TX_THREAD **owner,
TX_THREAD **first_suspended,
ULONG *suspended_count,
TX_MUTEX **next_mutex)
相关的代码示例已经在互斥锁获取函数中展示过了。
5.tx_mutex_prioritize
UINT tx_mutex_prioritize(TX_MUTEX *mutex_ptr)
互斥锁挂起列表的最高优先级线程置队头。
这样的好处是可依然高优先级的线程能更早得到互斥锁。
下面示例代码先调用互斥锁优先级函数,再释放互斥锁,根据串口打印结果显示两个操作都成功了。
void thread_1_entry(ULONG thread_input)
//线程1,控制led,只让他亮5s
{
TX_MUTEX *mutex_ptr=&mutex_0;
CHAR *name;
ULONG count;
TX_THREAD *owner;
TX_THREAD *first_suspended;
ULONG suspended_count;
TX_MUTEX *next_mute;
char cc[]="线程2\n";
HAL_UART_Transmit(&huart1, (uint8_t *)cc, strlen(cc), HAL_MAX_DELAY);
UINT status = tx_mutex_get(&mutex_0,TX_WAIT_FOREVER);
char buffer[256];
snprintf(buffer, sizeof(buffer),"%u\n",status);
HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
char buffer1[256];
UINT aa = tx_mutex_info_get(mutex_ptr, &name, &count, &owner, &first_suspended, &suspended_count, &next_mute);
snprintf(buffer1, sizeof(buffer1), "Name: %s, Count: %lu, Owner: %p, First Suspended: %p, Suspended Count: %lu, Next Mutex: %p\n",
name, count, owner, first_suspended, suspended_count, next_mute);
HAL_UART_Transmit(&huart1, (uint8_t *)buffer1, strlen(buffer1), HAL_MAX_DELAY);
UINT prioritize_status = tx_mutex_prioritize(&mutex_0);
char prioritize_buffer[256];
snprintf(prioritize_buffer, sizeof(prioritize_buffer), "Mutex Prioritize Status: %u\n", prioritize_status);
HAL_UART_Transmit(&huart1, (uint8_t *)prioritize_buffer, strlen(prioritize_buffer), HAL_MAX_DELAY);
// 释放互斥锁
UINT release_status = tx_mutex_put(&mutex_0);
char release_buffer[256];
snprintf(release_buffer, sizeof(release_buffer), "Mutex Release Status: %u\n", release_status);
HAL_UART_Transmit(&huart1, (uint8_t *)release_buffer, strlen(release_buffer), HAL_MAX_DELAY);
}
6.tx_mutex_put
释放互斥锁
每次得到互斥锁之后,要释放互斥锁,否则其他线程会无法得到互斥锁,导致死锁。
关于释放互斥锁的演示代码在互斥锁优先级中已经展示过了。