【POSIX标准头文件】<unistd.h>

系统操作

函数说明
getuid()获取UID(10000 * userId + AppId,默认用户userId = 0)
getpid获取进程ID
getppid获取父进程ID
gettid获取线程ID
fork创建子进程
execl在当前进程执行其他程序
sleep线程休眠,单位:秒
usleep线程休眠,单位:微秒
pipe管道
syscall系统调用

fork

fork被调用一次,能够返回两次,它可能有三种不同的返回值:

  • 在父进程中,fork返回新创建子进程的进程ID
  • 在子进程中,fork返回0
  • 如果出现错误,fork返回一个负值
void main() {
    pid_t pid = fork();
    LOGD("fork pid = %d", pid);
    if (pid == 0) {
        //子进程
    } else if (pid > 0) {
        //父进程
    }
}

pipe

参考linux 管道pipe使用,用管道进行通信的时候主要由如下两种局限性:

  • 管道是半双工的,及数据只能在一个方向上流动;
  • 管道只能在具有公共祖先的两个进程之间使用。通常一个管道由一个进程创建,在进程调用fork之后,这个管道就能在父进程和子进程之间使用了。
#define PIPE_READ 0
#define PIPE_WRITE 1

void main(){
    //数据流向:父->子
    int pipe2Child[2];
	//数据流向:子->父
    int pipe2Parent[2];

    if (-1 == pipe(pipe2Child)) {
        LOGE("fail create pipe2Child");
        return;
    }

    if (-1 == pipe(pipe2Parent)) {
        LOGE("fail create pipe2Parent");
        return;
    }

    int pid = fork();
    if (pid == -1) {
        LOGE("fail fork");
        return;
    }

    if (pid == 0) {
       	//子进程,关闭不需要的FD
        close(pipe2Parent[PIPE_READ]);
        close(pipe2Child[PIPE_WRITE]);

        //向父进程写入数据
        const char *writeBuffer = "hello, i am child";
        int writeResult = write(pipe2Parent[PIPE_WRITE], writeBuffer, strlen(writeBuffer));
        LOGD("write to parent success %d", writeResult);

        //从父进程读取数据
        char readBuffer[1024];
        memset(readBuffer, 0, 1024);
        read(pipe2Child[PIPE_READ], readBuffer, 1024);
        LOGD("read from parent = %s", readBuffer);
    } else {
		//父进程,关闭不需要的FD
        close(pipe2Parent[PIPE_WRITE]);
        close(pipe2Child[PIPE_READ]);

		//从子进程读取数据
        char readBuffer[1024];
        memset(readBuffer, 0, 1024);
        read(pipe2Parent[PIPE_READ], readBuffer, 1024);
        LOGD("read from child = %s", readBuffer);
        
		//向子进程写入数据
        const char *writeBuffer = "i am parent,i receive";
        int writeResult = write(pipe2Child[PIPE_WRITE], writeBuffer, strlen(writeBuffer));
        LOGD("write to child success %d", writeResult);
    }
}

execl

当用fork函数创建新的子进程后,子进程往往要调用一种exec函数以执行另一个程序。当程序调用一种exec函数时,该进程执行的程序完全替换为新程序,而新程序则从其main函数开始执行。因为调用exec并不创建新进程,所以前后的进程ID并未改变。exec只是用磁盘上的一个新程序替换了当前进程的正文段、数据段、堆段和栈段。

  • 参数1:文件路径
  • 参数2:文件标识符,例如文件名称
  • 参数3:执行程序需要的参数
int execl(const char *path, const char *arg, ...);

//例如执行 ls -l 命令
execl("/bin/ls", "ls", "-l", NULL);

同族还有其他相关函数,并且其命名有一定规律

  • 第5位 l:参数传递为逐个列举
  • 第5位 v:参数传递为构造指针数组方式
  • 第6位 e:可传递新进程环境变量
  • 第6位 p:可执行文件查找方式为文件名
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., 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[]);

文件操作

函数说明
read从文件描述符对应的文件中读取数据
write向文件描述符对应的文件中写入数据
lseek控制文件读写位置
dup复制文件描述符,指向同一个文件
truncate修改文件大小(参数为文件路径)
ftruncate修改文件大小(参数为文件描述符)
chown修改文件所有者
close关闭fd

read、write、lseek

int fd = open("/sdcard/tencent/test", O_RDWR);
const char *writeBuffer = "Happy NewYear 2023!";
//向fd中写入数据,返回值为写入数据的字节数
int writeResult = write(fd, writeBuffer, strlen(writeBuffer));

/*
 * 移动读写位置为文件开头
 * 参数2:偏移量
 * 参数3:偏移的起点,有如下三个
 * SEEK_SET 将读写位置指向文件头后再增加offset个位移量。
 * SEEK_CUR 以目前的读写位置往后增加offset个位移量。
 * SEEK_END 将读写位置指向文件尾后再增加offset个位移量。
 */
lseek(fd, 0, SEEK_SET);

char readBuffer[1024];
memset(readBuffer, 0, 1024);
//从fd中读取数据,返回值为读取的字节数
int readResult = read(fd, readBuffer, 1024);

truncate、ftruncate

在进行mmap内存映射之前就需要修改文件大小,否则可能导致映射失败(新建的文件大小为0,无法映射内存数据)

truncate("/sdcard/tencent/test_mmap", 1024);

int fd = open("/sdcard/tencent/test_mmap", O_RDWR);
ftruncate(fd, 1024);

dup

void main() {
    int fd = open("/sdcard/tencent/test", O_RDONLY);

    char buffer[1024];
    memset(buffer, 0, 1024);
    read(fd, buffer, 1024);
    LOGD("read old fd = %s", buffer);

    //复制fd,指向同一个文件
    int newFd = dup(fd);
    memset(buffer, 0, 1024);
    lseek(newFd, 0, SEEK_SET);
    read(newFd, buffer, 1024);
    LOGD("read new fd = %s", buffer);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值