嵌入式Linux:线程的创建、终止、回收、取消和分离

原创 美男子玩编程 2025-01-02 08:19

点击上方蓝色字体,关注我们

线程的创建、终止、取消、回收和分离操作是多线程编程的核心。


在多线程编程中,需要妥善管理线程的生命周期,以避免资源泄漏、竞争条件或僵尸线程等问题。


1


创建线程

在 Linux 中,默认情况下,一个进程启动时是单线程运行的,这个线程被称为 主线程


然而,现代计算任务通常需要并行处理,主线程可以通过 pthread_create() 函数创建额外的线程来并行执行任务。


这些额外的线程与主线程共享进程的资源(如内存空间、文件描述符等),但它们有独立的执行路径。


pthread_create() 函数的定义如下:


int pthread_create(pthread_t *thread, const pthread_attr_t *attr,                   void *(*start_routine) (void *), void *arg);


函数参数:

  • thread:这是一个 pthread_t 类型的指针,指向存储线程 ID 的变量。pthread_t 是用于唯一标识线程的类型,当创建线程成功时,该变量会被赋值为新线程的 ID,在后续的线程管理中使用。

  • attr:这是一个指向 pthread_attr_t 类型的指针,用于设置线程的属性。如果设置为 NULL,则使用线程的默认属性。这些属性包括线程是否分离(detached)、栈大小等。如果需要设置特定的属性,可以使用 pthread_attr_init() 和相关的属性函数。

  • start_routine:这是线程执行函数的指针。新线程创建后,会从这个函数开始执行。该函数必须符合以下原型:


void* (*start_routine)(void *arg);


它接收一个 void* 类型的参数(arg),并返回一个 void* 类型的返回值。


  • arg:这是传递给 start_routine 函数的参数。可以是任意类型的指针。如果不需要传递参数,可以设置为 NULL。如果需要传递多个参数,可以使用结构体将它们打包后通过该指针传入。


返回值:

  • 成功时返回 0。

  • 失败时返回错误号,表示失败的原因。例如,EAGAIN 表示系统资源不足无法创建新线程,EINVAL 表示传入的属性无效。


创建线程的关键点:

  • 线程 ID: 每个线程都有唯一的 ID,用于区分线程。创建线程时,pthread_create() 会将新线程的 ID 存储在 pthread_t 类型的变量中,便于后续操作。

  • 线程属性: 默认情况下,线程使用系统的默认属性。如果需要更改线程的属性,比如将其设置为 分离线程 或指定线程的栈大小,可以通过 pthread_attr_t 来设置。

  • 启动函数和参数: 新线程会从 start_routine 函数开始执行,并传入 arg 参数。可以通过将多个参数封装在结构体中,一并传递给该函数。


当一个新线程被创建后,它立即加入系统的 线程调度队列,并在合适的时机获取 CPU 执行时间。

由于调度是由操作系统控制的,所以无法预料新创建的线程和主线程谁会先执行。

如果程序对线程的执行顺序有严格要求,可以使用同步机制(如 互斥锁信号量)来控制线程间的执行顺序。

下面是一个创建线程并传递参数的简单示例:


void* thread_function(void* arg) {    int* num = (int*)arg;    printf("New thread running with argument: %d\n", *num);    return NULL;}
int main() { pthread_t thread; int arg = 42;
// 创建线程,传递参数 arg if (pthread_create(&thread, NULL, thread_function, &arg) != 0) { perror("pthread_create failed"); return 1; }
// 等待新线程执行完毕 pthread_join(thread, NULL);
printf("Main thread finished\n"); return 0;}


解释:

  • 线程函数 thread_function() 接收一个 void* 类型的参数,并将其强制转换为 int* 类型,打印传入的值。

  • 主线程 调用 pthread_create() 创建了一个新线程,并将 arg 作为参数传递给新线程的函数 thread_function()。

  • 创建线程后,主线程调用 pthread_join() 等待新线程完成执行。如果不使用 pthread_join(),主线程不会等待新线程结束,这可能导致程序提前退出。


2


终止线程

在 Linux 中,终止线程可以通过多种方式完成,不同的方式影响线程的退出行为和进程的状态管理。


我们详细说明几种终止线程的常用方法。


  • return: 当线程的 start 函数执行 return 时,线程正常终止,并返回指定的值,返回值可以通过 pthread_join() 获取。

  • pthread_exit(): 线程可以通过显式调用 pthread_exit() 来终止自身,pthread_exit() 允许线程在任何位置退出,返回的值也可以通过 pthread_join() 获取。

  • pthread_cancel(): 通过 pthread_cancel() 可以请求取消一个线程,线程需要响应取消请求才能终止。

  • exit() 和 _exit(): 当进程中的任意线程调用 exit()、_exit() 或 _Exit() 时,整个进程,包括所有线程,都会被终止。


2.1、通过 return 语句退出线程

线程的 start 函数(即传递给 pthread_create() 的函数)在执行完毕时,可以直接使用 return 语句返回。这种方式会使线程正常退出,并将返回值作为线程的退出码。


这与调用 pthread_exit() 类似。


void* thread_function(void* arg) {    // 执行一些任务    int result = 42;    return (void*)result; // 通过 return 语句退出线程}


在上面的代码中,线程执行完 thread_function() 后,通过 return 返回 result,并且这个返回值可以通过 pthread_join() 函数在主线程中获取。

2.2、通过 pthread_exit() 退出线程

pthread_exit() 是专门用于退出线程的函数,它允许线程在任何位置显式退出,而不是依赖于 return。


调用 pthread_exit() 后,线程的控制流会立即结束,不再执行后续代码。


pthread_exit() 函数原型:


void pthread_exit(void *retval);


参数 retval: retval 是一个 void* 类型的指针,指定线程的返回值,也就是线程的退出码。这个值可以被其他线程通过 pthread_join() 获取。


示例如下:


void* thread_function(void* arg) {    int* retval = (int*)arg;    printf("Thread exiting with value: %d\n", *retval);    pthread_exit(retval); // 显式退出线程并返回值}
int main() { pthread_t thread; int arg = 42; int* retval;
pthread_create(&thread, NULL, thread_function, &arg); pthread_join(thread, (void**)&retval); // 获取线程的退出码
printf("Thread returned: %d\n", *retval); return 0;}


解释:

  • 在该示例中,pthread_exit() 显式终止了线程,并返回参数 arg 的值。

  • 主线程通过 pthread_join() 获取了子线程的退出码。


2.3、通过 exit()、_exit() 或 _Exit() 终止整个进程

exit()、_exit() 和 _Exit() 不是用于终止单个线程的,而是用于终止整个进程。


由于线程共享同一个进程资源,如果任意一个线程调用这些函数,整个进程(包括所有线程)都会终止。

  • exit(): 正常终止进程,执行清理函数、关闭文件描述符等。

  • _exit() 和 _Exit(): 立即终止进程,不执行清理工作。


以下示例中,thread_function() 中调用了 exit(),导致整个进程被终止,主线程也不会继续执行。


void* thread_function(void* arg) {    printf("Thread running...\n");    exit(0); // 调用 exit(),导致整个进程终止    return NULL;}
int main() { pthread_t thread;
pthread_create(&thread, NULL, thread_function, NULL); pthread_join(thread, NULL);
// 如果没有被 exit() 终止,主线程会继续执行这行代码 printf("Main thread finished\n");
return 0;}

3


回收线程

在多线程编程中,当线程结束后,其占用的资源不会立即被系统释放,除非显式回收这些资源,否则这些线程会变成 僵尸线程


在 Linux 中,回收线程的操作与进程的回收类似。


正如进程中的父进程可以使用 wait() 来回收子进程的资源,线程中也需要通过 pthread_join() 来回收线程资源并获取线程的退出状态。


pthread_join() 是用于 等待指定线程终止并回收其资源 的函数,它会阻塞调用线程直到目标线程终止。


如果线程已经终止,pthread_join() 将立即返回。


通过这个函数,主线程或其他线程可以获取目标线程的退出状态,并清理其占用的资源,避免产生僵尸线程。


pthread_join() 的函数原型:


int pthread_join(pthread_t thread, void **retval);


函数参数说明:

  • thread: 这是目标线程的线程 ID,pthread_join() 将等待这个线程终止。

  • retval: 这是一个指向 void* 类型的指针,指向保存线程返回值的内存地址。如果目标线程通过 pthread_exit() 或 return 语句返回了某个值,这个值将被存储在 *retval 指向的内存中。如果 retval 为 NULL,则表示不关心目标线程的返回值。


返回值:

  • 成功时返回 0。

  • 如果调用失败,pthread_join() 将返回一个错误码。例如,ESRCH 表示指定的线程不存在,EINVAL 表示线程不可被 pthread_join() 回收,或者调用线程尝试等待自身终止。


以下例子中,线程执行完 thread_function() 后通过 pthread_exit() 返回 result。


主线程调用 pthread_join() 等待线程结束,并成功获取到了线程的返回值。


void* thread_function(void* arg) {    int result = 100;    printf("Thread running...\n");    pthread_exit((void*)&result); // 显式返回一个结果}
int main() { pthread_t thread; int* thread_result;
// 创建线程 pthread_create(&thread, NULL, thread_function, NULL);
// 回收线程并获取返回值 pthread_join(thread, (void**)&thread_result);
printf("Thread returned: %d\n", *thread_result); return 0;}


3.1、pthread_join() 的使用场景与注意事项

pthread_join() 是 阻塞函数,它会一直等待指定线程结束。如果目标线程需要执行大量计算或处理,调用 pthread_join() 的线程将一直处于等待状态,直到目标线程终止。


如果线程已经结束,pthread_join() 将立即返回。


以下示例中,主线程在调用 pthread_join() 时会等待 5 秒,直到 worker_function() 执行完毕为止。


void* worker_function(void* arg) {    sleep(5);  // 模拟一些长时间运行的操作    return NULL;}
int main() { pthread_t thread;
pthread_create(&thread, NULL, worker_function, NULL);
printf("Waiting for thread to finish...\n"); pthread_join(thread, NULL); // 阻塞等待线程结束
printf("Thread finished.\n"); return 0;}


在进程中,如果父进程不回收子进程,则子进程会变为 僵尸进程,占用系统资源。

同样的,如果一个线程终止后,没有被其他线程调用 pthread_join() 来回收,其内存和其他资源也不会被立即释放,这就导致了 僵尸线程 的问题。

僵尸线程不仅浪费资源,而且如果僵尸线程累积过多,可能会导致应用程序无法创建新的线程。

3.2、pthread_join() 与进程回收的区别

虽然 pthread_join() 与进程中的 waitpid() 类似,都是用于等待子线程(或子进程)结束并获取其退出状态,但二者之间有一些显著的区别:


1、线程关系是对等的。

在多线程程序中,任何线程都可以调用 pthread_join() 来等待另一个线程的结束。即使是非创建该线程的线程,也可以调用 pthread_join() 来等待它的终止。线程之间没有父子层级关系。


举例来说,如果线程 A 创建了线程 B,线程 B 创建了线程 C,那么线程 A 可以等待线程 C 的结束,而不需要依赖线程 B。


这与进程的父子层级结构不同,父进程是唯一可以调用 wait() 或 waitpid() 来等待子进程终止的进程。


2、pthread_join() 不支持非阻塞等待。

pthread_join() 是阻塞调用,不支持类似waitpid() 中的非阻塞模式(通过传入 WNOHANG 标志实现)。


这意味着线程调用 pthread_join() 后必须等待目标线程终止,不能做其他操作。如果需要更复杂的线程同步,通常需要引入其他机制,如 信号量条件变量 等。


4


取消线程

通常情况下,线程会自行决定何时结束,比如通过调用 pthread_exit() 函数或者在其启动函数中执行 return 语句。


但有些场景下,主线程或其他线程可能需要 强制终止 某个正在运行的线程,这时就可以通过 取消请求 来实现。


通过调用 pthread_cancel(),可以向目标线程发送一个取消请求,要求它终止。


pthread_cancel() 函数原型如下:


int pthread_cancel(pthread_t thread);


参数说明:

  • thread: 需要取消的目标线程的线程 ID。


返回值:

  • 成功时返回 0。

  • 如果调用失败,返回错误码,例如:ESRCH: 指定的线程不存在。


4.1、线程取消的响应机制

目标线程对取消请求的响应方式可以由其自身决定。每个线程都有一个 取消状态取消类型 来控制它对取消请求的响应:

4.1.1、取消状态

取消状态决定了线程是否允许响应取消请求,线程可以通过调用 pthread_setcancelstate() 来修改其取消状态。

  • PTHREAD_CANCEL_ENABLE: 表示线程 允许 响应取消请求(这是默认状态)。

  • PTHREAD_CANCEL_DISABLE: 表示线程 不允许 响应取消请求。即使收到了取消请求,线程仍会继续运行,直到其取消状态被重新设置为可取消。


pthread_setcancelstate() 函数原型:


int pthread_setcancelstate(int state, int *oldstate);


参数:

  • state: 可以是 PTHREAD_CANCEL_ENABLE 或 PTHREAD_CANCEL_DISABLE,分别表示开启或禁用取消请求的响应。

  • oldstate: 如果不为 NULL,将保存原先的取消状态。


示例如下:


pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); // 禁止取消请求pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);  // 允许取消请求

4.1.2、取消类型

取消类型决定了线程 何时 响应取消请求。


可以通过调用 pthread_setcanceltype() 来设置线程的取消类型:

  • PTHREAD_CANCEL_DEFERRED: 线程将在 某些特定的取消点 响应取消请求(例如调用 pthread_testcancel(),或进行 I/O 操作时)。这是默认的取消类型。

  • PTHREAD_CANCEL_ASYNCHRONOUS: 线程在 收到取消请求的瞬间 就立即响应,可能导致线程在任意位置被取消。


pthread_setcanceltype() 函数原型:

int pthread_setcanceltype(int type, int *oldtype);


参数:

  • type: 可以是 PTHREAD_CANCEL_DEFERRED 或 PTHREAD_CANCEL_ASYNCHRONOUS,分别表示延迟响应取消或立即响应取消。

  • oldtype: 如果不为 NULL,将保存原先的取消类型。


示例:

pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); // 设置为立即响应取消
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); // 设置为延迟响应取消


4.2、取消点与线程清理

当线程的取消类型设置为 PTHREAD_CANCEL_DEFERRED 时,线程只有在到达某些 取消点 时才会响应取消请求。


取消点通常是一些耗时操作或系统调用,比如:


  • pthread_testcancel(): 显式设置取消点。

  • 其他一些常见的系统调用,比如 I/O 操作、sleep()、select() 等,都是隐式取消点。



系统中还有许多函数可以作为取消点,这里不再逐一列举。您可以通过查看 man 手册获取更多信息,使用命令 man 7 pthreads 进行查询。 

pthread_testcancel() 函数原型:


void pthread_testcancel(void);


这个函数可以在代码的任意位置显式创建一个取消点。


调用 pthread_testcancel() 后,线程会检查是否有取消请求,如果有,线程将在此处退出。


示例如下:


while (1) {    // 执行一些任务    pthread_testcancel(); // 在循环中显式设置取消点,检查是否有取消请求}


4.3、线程清理处理函数

在线程终止时(无论是正常结束还是被取消),可以使用 清理处理函数 来进行资源清理。


清理处理函数可以确保线程在取消时能够正确释放资源,避免资源泄露。


使用 pthread_cleanup_push() 和 pthread_cleanup_pop() 来设置清理函数:

  • pthread_cleanup_push(void (*routine)(void *), void *arg):将一个清理函数 routine 压入栈,当线程退出时,系统将调用该函数。

  • pthread_cleanup_pop(int execute):将清理函数从栈中弹出,execute 表示是否执行该函数。


以下例子中,当线程收到取消请求后,它会在 pthread_testcancel() 函数处响应取消请求并退出。


在线程退出时,cleanup_handler() 会被调用以清理资源。


void cleanup_handler(void *arg) {    printf("Cleanup: %s\n", (char *)arg);}
void* thread_function(void* arg) { pthread_cleanup_push(cleanup_handler, "Thread resources"); // 设置清理函数 while (1) { printf("Thread running...\n"); sleep(1); pthread_testcancel(); // 检查是否有取消请求 } pthread_cleanup_pop(1); // 1 表示执行清理函数 return NULL;}
int main() { pthread_t thread; pthread_create(&thread, NULL, thread_function, NULL);
sleep(3); // 等待几秒钟 pthread_cancel(thread); // 发送取消请求 pthread_join(thread, NULL); // 等待线程结束 printf("Thread has been canceled.\n");
return 0;}


正确处理线程的取消操作对于复杂的多线程应用程序至关重要,特别是在执行长时间任务时,灵活管理线程的取消状态和清理行为能够有效提高系统的稳定性和可靠性。


  • pthread_cancel() 用于向目标线程发送取消请求,要求其终止,但目标线程是否终止取决于其取消状态和取消类型。

  • 线程可以通过 pthread_setcancelstate() 来控制是否响应取消请求,并通过 pthread_setcanceltype() 来控制何时响应。

  • 在使用 延迟取消 的情况下,线程只有在特定的 取消点 处才会检查取消请求,可以通过 pthread_testcancel() 显式设置取消点。

  • 清理处理函数 确保线程在被取消时能够正确释放资源,避免资源泄露。


5


分离线程

默认情况下,线程终止后,其资源不会立即被系统回收,除非有另一个线程通过 pthread_join() 函数显式地等待该线程终止,回收其资源。


但如果某些线程的退出状态和返回值对程序来说并不重要,且不希望手动调用 pthread_join(),可以将该线程设置为 分离状态


分离状态的线程在终止时,系统会自动回收它的资源。


要将线程设置为分离状态,可以调用 pthread_detach() 函数。


pthread_detach() 函数原型:


int pthread_detach(pthread_t thread);


参数说明:

  • thread: 需要分离的目标线程的线程 ID。


返回值:

  • 成功时返回 0。

  • 如果调用失败,返回错误码,例如:

    • ESRCH: 指定的线程不存在或已经被回收。

    • EINVAL: 线程已经处于分离状态。


调用 pthread_detach() 后,指定的线程会进入分离状态。

处于分离状态的线程在终止时,系统会自动回收其所有资源,而无需其他线程显式调用 pthread_join()。

分离状态是不可逆的,一旦线程被分离,就不能再通过 pthread_join() 获取该线程的返回状态或等待其结束。

以下例子中,创建了一个新线程,并通过 pthread_detach() 将其分离。之后,无需调用 pthread_join(),系统将在该线程终止时自动回收它的资源。


pthread_t thread;pthread_create(&thread, NULL, thread_function, NULL);pthread_detach(thread); // 将该线程设置为分离状态


线程不仅可以由其他线程分离,还可以通过调用 pthread_detach(pthread_self()) 来 分离自己

这意味着该线程在终止时不需要其他线程来回收资源,系统将自动处理。

示例如下:


void* thread_function(void* arg) {    pthread_detach(pthread_self()); // 分离自己    // 线程执行的其他操作    pthread_exit(NULL);}


线程分离机制特别适用于以下几种场景:

  • 不关心线程的返回值: 如果线程执行的任务不需要返回值,且不希望其他线程显式地等待它结束。

  • 避免僵尸线程: 僵尸线程是指已经终止但资源未被回收的线程,长时间存在僵尸线程会消耗系统资源。将线程设置为分离状态,可以避免僵尸线程的产生。

  • 长时间运行的后台任务: 如果线程运行时间较长或是后台任务,而主线程不需要等待其结束,分离该线程可以简化资源管理。


线程分离与 pthread_join() 的比较:


线程分离:

  • 使用 pthread_detach() 将线程设置为分离状态。

  • 系统在线程终止时自动回收资源。

  • 无法通过 pthread_join() 获取线程的返回值或等待线程终止。


pthread_join():

  • 主动调用 pthread_join() 等待指定线程终止并回收资源。

  • 可以获取线程的返回值或终止状态。

  • 若没有调用 pthread_join(),线程终止后会成为僵尸线程,直到其资源被回收。


线程分离在简化多线程程序的资源管理方面非常有用,特别是对于一些无需等待或回收的线程,可以通过分离机制优化程序的性能和稳定性。

最后讲两点注意事项:

  • 不可逆性: 一旦线程被设置为分离状态,就无法恢复到可被 pthread_join() 回收的状态。如果你将某个线程分离,后续便无法获取其返回值或等待它结束。

  • 线程同步问题: 如果某个线程执行的任务需要与其他线程同步完成,则不应将其分离。否则,主线程或其他线程可能无法等待该线程结束,导致任务未完成就继续执行。

点击阅读原文,更精彩~

美男子玩编程 多领域、有深度的开发者交流平台
评论
  • 从无到有:智能手机的早期探索无线电话装置的诞生:1902 年,美国人内森・斯塔布菲尔德在肯塔基州制成了第一个无线电话装置,这是人类对 “手机” 技术最早的探索。第一部移动手机问世:1938 年,美国贝尔实验室为美国军方制成了世界上第一部 “移动” 手机。民用手机的出现:1973 年 4 月 3 日,摩托罗拉工程师马丁・库珀在纽约曼哈顿街头手持世界上第一台民用手机摩托罗拉 DynaTAC 8000X 的原型机,给竞争对手 AT&T 公司的朋友打了一个电话。这款手机重 2 磅,通话时间仅能支持半小时
    Jeffreyzhang123 2025-01-02 16:41 152浏览
  • 光耦合器,也称为光隔离器,是一种利用光在两个隔离电路之间传输电信号的组件。在医疗领域,确保患者安全和设备可靠性至关重要。在众多有助于医疗设备安全性和效率的组件中,光耦合器起着至关重要的作用。这些紧凑型设备经常被忽视,但对于隔离高压和防止敏感医疗设备中的电气危害却是必不可少的。本文深入探讨了光耦合器的功能、其在医疗应用中的重要性以及其实际使用示例。什么是光耦合器?它通常由以下部分组成:LED(发光二极管):将电信号转换为光。光电探测器(例如光电晶体管):检测光并将其转换回电信号。这种布置确保输入和
    腾恩科技-彭工 2025-01-03 16:27 104浏览
  • 在快速发展的能源领域,发电厂是发电的支柱,效率和安全性至关重要。在这种背景下,国产数字隔离器已成为现代化和优化发电厂运营的重要组成部分。本文探讨了这些设备在提高性能方面的重要性,同时展示了中国在生产可靠且具有成本效益的数字隔离器方面的进步。什么是数字隔离器?数字隔离器充当屏障,在电气上将系统的不同部分隔离开来,同时允许无缝数据传输。在发电厂中,它们保护敏感的控制电路免受高压尖峰的影响,确保准确的信号处理,并在恶劣条件下保持系统完整性。中国国产数字隔离器经历了重大创新,在许多方面达到甚至超过了全球
    克里雅半导体科技 2025-01-03 16:10 71浏览
  • 本文继续介绍Linux系统查看硬件配置及常用调试命令,方便开发者快速了解开发板硬件信息及进行相关调试。触觉智能RK3562开发板演示,搭载4核A53处理器,主频高达2.0GHz;内置独立1Tops算力NPU,可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。查看系统版本信息查看操作系统版本信息root@ido:/# cat /etc/*releaseDISTRIB_ID=UbuntuDISTRIB_RELEASE=20.04DISTRIB_CODENAME=focalDIS
    Industio_触觉智能 2025-01-03 11:37 86浏览
  • 影像质量应用于多个不同领域,无论是在娱乐、医疗或工业应用中,高质量的影像都是决策的关键基础。清晰的影像不仅能提升观看体验,还能保证关键细节的准确传达,例如:在医学影像中,它对诊断结果有着直接的影响!不仅如此,影像质量还影响了:▶ 压缩技术▶ 存储需求▶ 传输效率随着技术进步,影像质量的标准不断提高,对于研究与开发领域,理解并提升影像质量已成为不可忽视的重要课题。在图像处理的过程中,硬件与软件除了各自扮演着不可或缺的基础角色,有效地协作能够确保图像处理过程既高效又具有优异的质量。软硬件各扮演了什么
    百佳泰测试实验室 2025-01-03 10:39 79浏览
  • 车身域是指负责管理和控制汽车车身相关功能的一个功能域,在汽车域控系统中起着至关重要的作用。它涵盖了车门、车窗、车灯、雨刮器等各种与车身相关的功能模块。与汽车电子电气架构升级相一致,车身域发展亦可以划分为三个阶段,功能集成愈加丰富:第一阶段为分布式架构:对应BCM车身控制模块,包含灯光、雨刮、门窗等传统车身控制功能。第二阶段为域集中架构:对应BDC/CEM域控制器,在BCM基础上集成网关、PEPS等。第三阶段为SOA理念下的中央集中架构:VIU/ZCU区域控制器,在BDC/CEM基础上集成VCU、
    北汇信息 2025-01-03 16:01 117浏览
  • 在测试XTS时会遇到修改产品属性、SElinux权限、等一些内容,修改源码再编译很费时。今天为大家介绍一个便捷的方法,让OpenHarmony通过挂载镜像来修改镜像内容!触觉智能Purple Pi OH鸿蒙开发板演示。搭载了瑞芯微RK3566四核处理器,树莓派卡片电脑设计,支持开源鸿蒙OpenHarmony3.2-5.0系统,适合鸿蒙开发入门学习。挂载镜像首先,将要修改内容的镜像传入虚拟机当中,并创建一个要挂载镜像的文件夹,如下图:之后通过挂载命令将system.img镜像挂载到sys
    Industio_触觉智能 2025-01-03 11:39 78浏览
  • 前言近年来,随着汽车工业的快速发展,尤其是新能源汽车与智能汽车领域的崛起,汽车安全标准和认证要求日益严格,应用范围愈加广泛。ISO 26262和ISO 21448作为两个重要的汽车安全标准,它们在“系统安全”中扮演的角色各自不同,但又有一定交集。在智能网联汽车的高级辅助驾驶系统(ADAS)应用中,理解这两个标准的区别及其相互关系,对于保障车辆的安全性至关重要。ISO 26262:汽车功能安全的基石如图2.1所示,ISO 26262对“功能安全”的定义解释为:不存在由于电子/电气系统失效引起的危害
    广电计量 2025-01-02 17:18 175浏览
  • 自动化已成为现代制造业的基石,而驱动隔离器作为关键组件,在提升效率、精度和可靠性方面起到了不可或缺的作用。随着工业技术不断革新,驱动隔离器正助力自动化生产设备适应新兴趋势,并推动行业未来的发展。本文将探讨自动化的核心趋势及驱动隔离器在其中的重要角色。自动化领域的新兴趋势智能工厂的崛起智能工厂已成为自动化生产的新标杆。通过结合物联网(IoT)、人工智能(AI)和机器学习(ML),智能工厂实现了实时监控和动态决策。驱动隔离器在其中至关重要,它确保了传感器、执行器和控制单元之间的信号完整性,同时提供高
    腾恩科技-彭工 2025-01-03 16:28 120浏览
  • Matter加持:新世代串流装置如何改变智能家居体验?随着现在智能家庭快速成长,串流装置(Streaming Device,以下简称Streaming Device)除了提供更卓越的影音体验,越来越多厂商开始推出支持Matter标准的串流产品,使其能作为智能家庭中枢,连结多种智能家电。消费者可以透过Matter的功能执行多样化功能,例如:开关灯、控制窗帘、对讲机开门,以及操作所有支持Matter的智能家电。此外,再搭配语音遥控器与语音助理,打造出一个更加智能、便捷的居家生活。支持Matter协议
    百佳泰测试实验室 2025-01-03 10:29 95浏览
  • 国际标准IPC 标准:IPC-A-600:规定了印刷电路板制造过程中的质量要求和验收标准,涵盖材料、外观、尺寸、焊接、表面处理等方面。IPC-2221/2222:IPC-2221 提供了用于设计印刷电路板的一般原则和要求,IPC-2222 则针对高可靠性电子产品的设计提供了进一步的指导。IPC-6012:详细定义了刚性基板和柔性基板的要求,包括材料、工艺、尺寸、层次结构、特征等。IPC-4101:定义了印刷电路板的基板材料的物理和电气特性。IPC-7351:提供了元件封装的设计规范,包括封装尺寸
    Jeffreyzhang123 2025-01-02 16:50 167浏览
  • 【工程师故事】+半年的经历依然忧伤,带着焦虑和绝望  对于一个企业来说,赚钱才是第一位的,对于一个人来说,赚钱也是第一位的。因为企业要活下去,因为个人也要活下去。企业打不了倒闭。个人还是要吃饭的。企业倒闭了,打不了从头再来。个人失业了,面对的不仅是房贷车贷和教育,还有找工作的焦虑。企业说,一个公司倒闭了,说明不了什么,这是正常的一个现象。个人说,一个中年男人失业了,面对的压力太大了,焦虑会摧毁你的一切。企业说,是个公司倒闭了,也不是什么大的问题,只不过是这些公司经营有问题吧。
    curton 2025-01-02 23:08 199浏览
  • 物联网(IoT)的快速发展彻底改变了从智能家居到工业自动化等各个行业。由于物联网系统需要高效、可靠且紧凑的组件来处理众多传感器、执行器和通信设备,国产固态继电器(SSR)已成为满足中国这些需求的关键解决方案。本文探讨了国产SSR如何满足物联网应用的需求,重点介绍了它们的优势、技术能力以及在现实场景中的应用。了解物联网中的固态继电器固态继电器是一种电子开关设备,它使用半导体而不是机械触点来控制负载。与传统的机械继电器不同,固态继电器具有以下优势:快速切换:确保精确快速的响应,这对于实时物联网系统至
    克里雅半导体科技 2025-01-03 16:11 116浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦