getcwd

功能说明:

  • buf:用于存储当前工作目录路径的字符数组缓冲区
  • size:缓冲区的大小(以字节为单位)
  • 函数返回值:成功时返回指向缓冲区的指针(即 buf),失败时返回 NULL,并设置 errno
char *getcwd(char *buf, size_t size);
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main() {
    // 定义缓冲区,通常 PATH_MAX 是系统定义的最大路径长度
    char cwd[1024];
    
    // 获取当前工作目录
    if (getcwd(cwd, sizeof(cwd)) != NULL) {
        printf("当前工作目录: %s\n", cwd);
    } else {
        perror("获取目录失败");
        return 1;
    }
    
    return 0;
}


线程(Thread)

线程是进程内的一个执行单元,多个线程共享进程的资源,但拥有各自的执行栈和寄存器状态。

优点: 比多进程节省资源,可以共享变量。

    概念:线程是轻量级进程,一般是一个进程中的多个任务。
    进程是系统中最小的资源分配单位.
    线程是系统中最小的执行单位。

    特征:
    1、共享资源
    2、效率高  30%
    3、三方库: pthread  clone   posix
            3.1 编写代码头文件: pthread.h
            3.2 编译代码加载库: -lpthread   library 
            libpthread.so (库文件)
            gcc 1.c -lpthread 
    缺点:

    1,线程和进程相比,稳定性,稍微差些
    2,线程的调试gdb,相对麻烦些。

区别

线程与进程区别

    资源:
        线程比进程多了共享资源。  IPC
        线程又具有部分私有资源。
        进程间只有私有资源没有共享资源。
    空间:
        进程空间独立,不能直接通信。
        线程可以共享空间,可以直接通信。

特性进程线程
资源分配拥有独立的内存空间和资源共享所属进程的资源
开销创建和切换开销大创建和切换开销小
通信需要使用进程间通信 (IPC) 机制可直接访问共享内存
独立性相互独立,一个崩溃不影响其他同属一个进程,一个崩溃可能影响整个进程
调度由操作系统调度由操作系统调度,但开销更小

适用场景

  • 进程:适合需要完全隔离的任务,如运行不同的应用程序
  • 线程:适合需要共享数据且通信频繁的任务,如一个应用程序的不同功能模块
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

// 线程函数
void *thread_function(void *arg) {
    int thread_num = *(int *)arg;
    for (int i = 0; i < 5; i++) {
        printf("线程 %d: 计数 %d\n", thread_num, i);
        sleep(1);
    }
    return NULL;
}

int main() {
    pthread_t thread1, thread2;
    int num1 = 1, num2 = 2;
    
    // 创建线程
    if (pthread_create(&thread1, NULL, thread_function, &num1) != 0) {
        perror("创建线程1失败");
        return 1;
    }
    
    if (pthread_create(&thread2, NULL, thread_function, &num2) != 0) {
        perror("创建线程2失败");
        return 1;
    }
    
    // 等待线程结束
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    
    printf("所有线程执行完毕\n");
    return 0;
}

注意一次pthread_create执行只能创建一个线程。
              每个进程至少有一个线程称为主线程。
      主线程退出  则所有创建的子线程都退出。 
      主线程必须有子线程同时运行才算多线程程序。
      线程id是线程的唯一标识,是CPU维护的一组数字。
      pstree 查看系统中多线程的对应关系。
      多个子线程可以执行同一回调函数。


    ps -eLf 查看线程相关信息Low Weigth Process
    ps -eLo pid,ppid,lwp,stat,comm

pthread_t pthread_self(void); unsigned long int; %lu
   功能:获取当前线程的线程id
   参数:无
   返回值:成功 返回当前线程的线程id
               失败  -1;
 

练习题:
    设计一个多线程程序,至少有三个子线程
    每个线程执行不同的任务,并实时打印执行
    过程,同时表明身份。

线程的退出  

 1: 自行退出               ==》                   自杀               ==》       子线程自己退出
        exit(1);
        void pthread_exit(void *retval);  exit  return p;
        功能:子线程自行退出
        参数: retval 线程退出时候的返回状态,临死遗言。
        返回值:无

    2: 强制退出 ==》他杀  ==》主线程结束子线程
        int pthread_cancel(pthread_t thread);
        功能:请求结束一个线程
        参数:thread 请求结束一个线程tid
        返回值:成功 0
                       失败 -1;

线程的回收

1、线程的回收机制 ====》不同与进程没有孤儿线程和僵尸线程。
                                  ====》主线程结束任意生成的子线程都会结束。
                                          ====》子线程的结束不会影响主线程的运行。
    char * retval ;   retval++;  1 
    int * retval; 
    int pthread_join(pthread_t thread, void **retval);    
          功能:通过该函数可以将指定的线程资源回收,该函数具有阻塞等待功能,如果指定的线程没有结束,则回收线程会阻塞。
          参数:thread  要回收的子线程tid
                     retval   要回收的子线程返回值/状态。       ==》ptread_exit(值);
          返回值:    成功 0
                            失败 -1;

  子线程的回收策略
  1、如果预估子线程可以有限范围内结束则正常用pthread_join等待回收。
  2、如果预估子线程可能休眠或者阻塞则等待一定时间后强制回收。
  3、如果子线程已知必须长时间运行则,不再回收其资源。

关于局部变量的解决,1.static 

                                    2.malloc  (需要free)


atoi()           atof() 

线程的参数,返回值

1、传参数
     传整数 


    传字符串
        栈区字符数组:
        字符串常量:
        char *p = "hello";
        堆区字符串;
   

传结构体
    1、定义结构体类型
    2、用结构体定义变量
    3、向pthread_create传结构体变量
    4、从fun子线程中获取结构体数据


设置分离属性

设置分离属性,目的线程消亡,自动回收空间。

    attribute
    int pthread_attr_init(pthread_attr_t *attr);
    功能,初始化一个attr的变量
    参数:attr,需要变量来接受初始值
    返回:0  成功,
    非0 错误;
       int pthread_attr_destroy(pthread_attr_t *attr);
      功能:销毁attr变量。
      attr,属性变量
      返回:0  成功,
    非0 错误;
 

int pthread_deatch(pthread_t thread);
    功能,设置分离属性   将指定的线程标记为 “分离状态”(detached state)。
    参数,线程id号,填自己的id

注意:一旦线程被标记为分离状态,就不能再通过 pthread_join() 获取其返回值了。


void pthread_cleanup_push(void (*routine)(void *), void *arg);

    功能:注册一个线程清理函数
    参数,routine,线程清理函数的入口
                arg,清理函数的参数。
    返回值,无
        
void pthread_cleanup_pop(int execute);
    功能:调用清理函数
    execute,非0  执行清理函数
                    0 ,不执行清理          
                    返回值,无


Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐