1.exec函数族
extern char **environ;int execl(const char *path, const char *arg, ...
/* (char *) NULL */);
int execlp(const char *file, const char *arg, ...
/* (char *) NULL */);
int execle(const char *path, const char *arg, ...
/*, (char *) NULL, char * const envp[] */);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],
char *const envp[]);功能:
利用进程空间执行另外一份代码
l:参数以列表形式传递
v:参数以指针数组形式传递
e:更新环境变量
p:在系统指定目录下查找文件
注意:
execl 默认在当前目录下寻找
或者
execlp默认在系统目录下寻找
更改路路径到当前目录
或者
getenv
char *getenv(const char *name);
功能:
获得环境变量名对应的值
setenv
int setenv(const char *name, const char *value, int overwrite);
功能:
设置环境变量的值
参数:
name:环境变量名
value:环境变量的值
overwrite:非0 覆盖
0 不覆盖
返回值:
成功返回0
失败返回-1
2.线程:
1.基本概念:
线程:线程是一个轻量级的进程,位于进程空间内部,一个进程中可以创建多个线程
2.线程创建:
线程独占一个栈空间, 文本段、数据段和堆区与进程共享
3.线程调度:
与进程调度是一样的
宏观并行,微观串行
4.线程消亡:
与进程消亡是一样的
5.进程和线程的区别:
进程是操作系统资源分配的最小单元
线程是CPU任务调度的最小单元
6.函数和线程的区别:
被调函数执行完后主函数才继续向下执行
线程在被创建后和进程同时向下执行
7.多进程和多线程的优缺点:
效率 : 多线程 > 多进程
多线程只需在同一进程空间内切换
多进程需要在不同的空间中切换
通信 : 多线程 > 有进程
线程共享全局变量,可以通过全局变量实现数据通信
进程空间是独立的,没有共享空间,通信实现比较复杂
通信实现 : 多进程 > 多线程
线程共享空间操作时会引发资源竞争(通过使用时上锁,使用后解锁来解决)
进程没有共享空间,不存在资源竞争的问题
安全 : 多进程 > 多线程
一个进程异常不会影响其余进程空间
一个线程异常结束会导致进程异常结束,进程异常结束,该进程内所有线程任务均无法向下执行
8.线程相关的函数接口:
创建: fork pthread_create
退出: exit pthread_exit
回收: wait pthread_join
1.pthread_create
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
功能:
在该进程中创建一个新的线程
参数:
thread:存放线程ID空间首地址
attr:线程属性空间首地址
start_routine:线程要执行的函数的入口
arg:给线程函数的参数
返回值:
成功返回0
失败返回错误码编译时加 -lpthread选项
2.pthread_self
pthread_t pthread_self(void);
功能:
获得调用该函数线程的ID
3.pthread_exit
void pthread_exit(void *retval);
功能:
让调用该函数的线程任务结束
参数:
retval:线程结束的值
4.pthread_join
int pthread_join(pthread_t thread, void **retval);
功能:
回收线程空间
参数:
thread:线程的ID号
retval:存放线程结束状态空间的首地址
返回值:
成功返回0
失败返回错误码
3.何时用到二级指针(题外话)
1.指针数组传参时,用到二级指针
指针数组是一个包含多个指针元素的数组。每个指针元素可以指向不同的数据类型或数据结构。通过传递指针数组的地址(即指针数组的数组名),被调函数可以直接访问和修改数组中的元素。
#include <stdio.h>
// 函数原型,接受一个指针数组作为参数
void printPointers(int *ptrArr[], int size)
{
for (int i = 0; i < size; i++)
{
printf("%p\n", ptrArr[i]);
}
}
int main()
{
int num1 = 10;
int num2 = 20;
int num3 = 30;
// 定义一个指针数组,包含三个整型指针
int *ptrArr[] = {&num1, &num2, &num3};
// 将指针数组传递给函数
printPointers(ptrArr, 3);
return 0;
}
定义了一个指针数组 ptrArr
,其中包含三个整型指针,分别指向变量 num1
、num2
和 num3
。然后,我们将指针数组传递给 printPointers
函数,它会遍历指针数组并打印每个指针的地址。
2.被调修改主调时,用到二级指针
函数传参是值传递,形参只是实参的副本,形参值如何变化不影响实参的值