Linux系统编程——笔记

本文详细介绍了Linux系统编程,涵盖文件操作、进程管理、进程间通信(IPC)、线程使用和Linux网络编程。讨论了exec族函数、信号处理、管道、FIFO、消息队列、共享内存和信号量,以及线程的创建、互斥锁和条件变量。还提到了进程的生命周期、孤儿进程和僵尸进程。最后简要概述了TCP与UDP的区别以及Socket编程的基本步骤。
摘要由CSDN通过智能技术生成

一、文件

 API:open()、read()、write()、close()、lseek()

//int open(const char *pathname, int flags);
//return:成功打开或创建返回int型文件描述符,错误打开或创建返回-1.
open("./pathname",O_CREAT|O_RDWR,0666);
open("./pathname",O_RDWR);

//ssize_t read(int fd, void *buf, size_t count);
//ssize_t write(int fd, const void *buf, size_t count);
//return:On success, the number of bytes read is returned.On error, -1 is returned.

//int close(int fd);

//off_t lseek(int fd, off_t offset, int whence);
//参数1.fd:操作文件fd  2.offset:一般为0 3.whence:SEEK_SET SEEK_END 

int size = lseek(fd,0,SEEK_END);
//光标在文件中从0(开头)到END移动的次数size(文件大小),光标在文件最后
lseek(fd,0,SEEK_SET);
//光标在文件的开头

二、进程

程序是静态的概念,进程是动态的概念。

查看进程状态:1.ps(当前系统进程状态) 2.top(实时显示系统各个进程资源占用情况)

ps指令:

a.ps -aux 显示进程

b.ps -aux xxx 显示含xxx的进程

c.ps aux | grep xxx //查到使用xxx的进程

top指令:top [-d number] | top [-bnp]

进程标识符:每一个进程都有一个非负整数表示的唯一ID,叫做PID。getpid()函数获取自身的进程标识符;getppid()函数获取父进程的进程标识符。

c内存存储空间分配:

数据段:存放初始化后的变量

bss:存放未初始化的变量

堆:malloc中申请的空间在堆中

栈:函数调用,函数调用的局部变量和返回值的存放。 

父子进程

pid_t fork(void);//创建子进程 
父子进程:A创建B,A为父进程,B为子进程
调用成功返回两次: 返回为0 为子进程;返回为非负 为父进程
调用失败返回-1

int main()
{
        int data;
        pid_t pid;
        while(1){
                printf("Please scanf a data:\n");
                scanf("%d",&data);
                if(data==1){
                        pid=fork();
                        if(pid>0){
                                wait(NULL);
                        }
                        if(pid==0){
                                //execl("./changdata","changdata","congfig.txt",NULL);
                                system("./changdata congfig.txt");
                                exit(0);
                        }
                }else{
                        printf("that nothing!\n");
                }
        }
        return 0;
}

 

 vfork():直接使用父进程的存储空间不进行拷贝;保证子进程先运行,调用exit函数退出后,父进程才执行。

进程退出:

        a正常退出:1.main调用return 2.进程调用exit() 标准c库 3.进程调用_exit()、_Exit() 系统调用 (补充:进程最后一个线程返回;最后一个线程调用pthread_exit)

        b异常退出:1.调用abort 2.Ctrl+c 3.最后一个线程对取消请求做出响应

孤儿进程:父进程不等待子进程退出,在子进程之前就结束了自己的“生命”,此时子进程叫做孤儿进程。

父进程等待子进程退出用exit() 正常退出用WEXITSTATUS()刷新。

 exec族函数

  execl、execlp、execle、exexv、execvp、execupe

功能:调用进程内部执行一个可执行文件。可执行文件可以是内部的二进制文件也可以是linux下可执行脚本文件。

#include <unistd.h>
extern char **environ;

int execl(const char *path, const char *arg, ...);
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[]);

exec族函数参数极难记忆和分辨,函数名中的字符会给我们一些帮助:
l : 使用参数列表
p:使用文件名,并从PATH环境进行寻找可执行文件
v:应先构造一个指向各参数的指针数组,然后将该数组的地址作为这些函数的参数。
e:多了envp[]数组,使用新的环境变量代替调用进程的环境变量

 参考exec族函数链接:

(80条消息) linux进程---exec族函数(execl, execlp, execle, execv, execvp, execvpe)_云英的博客-CSDN博客_execvpe

echo $PETH :打印环境变量  export PATH= PATH:路径 添加环境变量

//int system(const char *command);

//FILE *popen(const char *command, const char *type);
//int pclose(FILE *stream);
//size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
//popen()配合fread()进行使用最后pclose()

//popen 可以获取输出结果

/*总的来说,请求popen调用运行一个程序时,它首先启动shell,即系统的shell命令,然后将command字符串作为一个参数传递给它。这样就有了优缺点:
优点是:由于所有类Unix系统中参数扩展都是由shell完成的,所有它运行我们通过popen完成非常复杂的shell命令。而其他一些创建进程的函数(如execl)调用起来就复杂的多,因为调用进程必须自己完成shell扩展。
缺点是:针对每个popen调用,不仅要启动一个被请求的程序,还要启动一个shell,即每个popen调用将启动两个进程。从节省系统资源的角度来看,popen函数的调用成本略高,并且对目标命令的调用比正常方式慢一些(通过pipe改进)。

和system相比,system就是执行shell命令最后返回是否执行成功,popen执行命令并且通过管道和shell命令进行通信。*/

僵尸进程:原因进程没有释放

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值