Linux环境编程

1.进程

1.1进程标志

    #include <unistd>;
    pid_t getpid(void);//获得进程ID
    pid_t getppid(void);//获得父进程ID
    #include <unistd>;
    #include <sys/types.h>;
    uid_t getuid(void);//获得用户ID
    uid_t geteuid(void);//获得有效用户ID
    gid_t getgid(void);//获得组ID
    git_t getegid(void);//获得有效组ID
    #include <pwd.h>;
    #include <sys/types.h>;
    struct passwd *getpwuid(uid_t uid);
        struct passwd {
        char *pw_name; /* 登录名称 */
        char *pw_passwd; /* 登录口令 */
        uid_t pw_uid; /* 用户 ID */
        gid_t pw_gid; /* 用户组 ID */
        char *pw_gecos; /* 用户的真名 */
        char *pw_dir; /* 用户的目录 */
        char *pw_shell; /* 用户的 SHELL */
    };

1.2进程创建

    #include <unistd.h>;
    pid_t fork();
    /*
        return  失败 -1  成功 子进程 0  父进程 子进程ID
    */

1.3进程阻塞

    #include <sys/types.h>;
    #include <sys/wait.h>;
    pid_t wait(int *stat_loc);
    /*
        父进程阻塞直到一个子进程结束或者父进程接受到了一个信号,如果没有父进程没有子进程或者其他的子进程已经结束了wait会立即返回。
        成功时,wait将返回子进程的ID,否则返回-1,并设置全局变量errno。

        stat_loc是子进程的退出状态。子进程调用exit,_exit或者是return来设置这个值,为了得到这个值Linux定义了几个宏来测试这个返回值。

        WIFEXITED(status):判断子进程退出值是非 0.
        WEXITSTATUS(status):判断子进程的退出值(当子进程退出时非 0).
        WIFSIGNALED(status):子进程由于有没有获得的信号而退出.
        WTERMSIG(status):子进程没有获得的信号号(在 WIFSIGNALED 为真时才有意义).
    */
    pid_t waitpid(pid_t pid,int *stat_loc,int options); 
    /*
        等待指定的子进程直到子进程返回。如果 pid 为正值则等待指定的进程(pid)。如果为 0 则等待任何一个组 ID 和调用者的组 ID 相同的进程,为-1 时等同于 wait 调用,小于-1 时等待任何一个组 ID 等于 pid 绝对值的。stat_loc 和 wait 的意义一样,options 可以决定父进程的状态 。
        optios可以取两个值 :
        WNOHANG:父进程立即返回当没有子进程存在时 。
        WUNTACHED:当子进程结束时 waitpid 返回,但是子进程的退出状态不可得到。
    */

1.4exec族

    /*exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件。这里的可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件。*/
    #include <unistd.h>;
    int execl(const char *path,const char *arg,...);
    int execlp(const char *file,const char *arg,...);
    int execle(const char *path,const char *arg,...);
    int execv(const char *path,char *const argv[]);
    int execvp(const char *file,char *const argv[]);

1.5进程挂起

    #include <unistd.h>
    usleep(微妙)
    Sleep(毫秒) 
    sleep(秒);
    //若进程/线程挂起到参数所指定的时间则返回0,若有信号中断则返回剩余秒数。

2.文件

2.1文件读写和创建

    #include <fcntl.h>;
    #include <unistd.h>;
    #include <sys/types.h>;
    #include <sys/stat.h>;
    int open(const char *pathname,int flags);
    //pathname 打开的文件名(包含路径名称,缺省:在当前路径下面).
    //flags 可以去下面的一个值或者是几个值的组合.
    //return 文件描述符
    /* (前三个标志是唯一标志只能用一个)
        O_RDONLY:以只读的方式打开文件.
        O_WRONLY:以只写的方式打开文件.
        O_RDWR:以读写的方式打开文件.
        O_APPEND:以追加的方式打开文件.
        O_CREAT:创建一个文件.
        O_EXEC:如果使用了 O_CREAT 而且文件已经存在,就会发生一个错误.
        O_NOBLOCK:以非阻塞的方式打开一个文件.
        O_TRUNC:如果文件已经存在,则删除文件的内容.
    */

    int open(const char *pathname,int flags,mode_t mode);
    /*
        如果使用了 O_CREATE 标志,那么我们要使用 open 的第二种形式.还要
        指定 mode 标志,用来表示文件的访问权限.mode 可以是以下情况的组合.
        -------------------------------------------------------
        S_IRUSR 用户可以读 S_IWUSR 用户可以写
        S_IXUSR 用户可以执行 S_IRWXU 用户可以读写执行
        -------------------------------------------------------
        S_IRGRP 组可以读 S_IWGRP 组可以写
        S_IXGRP 组可以执行 S_IRWXG 组可以读写执行
        -------------------------------------------------------
        S_IROTH 其他人可以读 S_IWOTH 其他人可以写
        S_IXOTH 其他人可以执行 S_IRWXO 其他人可以读写执行
        -------------------------------------------------------
        S_ISUID 设置用户执行 ID S_ISGID 设置组的执行 ID
        -------------------------------------------------------
    */
    int close(int fd);
    //fd文件描述符


    #include <unistd.h>;
    ssize_t read(int fd, void *buffer,size_t count);
    ssize_t write(int fd, const void *buffer,size_t count);
    /*
      fd     行读写操作的文件描述符,
      buffer 写入文件内容或读出文件内容存放的内存地址.
      count  要读写的字节数.
    */

2.2判断文件属性

    int access(const char *pathname,int mode)
    /*
        pathname:文件名称,
        mode    :判断的属性.
        可以取
        R_OK 文件可以读,
        W_OK 文件可以写,
        X_OK 文件可以执行,
        F_OK 文件存在.
        或者是他们的组合.
        成功时 ,函数返回 0,否则如果有一个条件不符时,返回-1.
    */
    #include <unistd.h>;
    int stat(const char *file_name,struct stat *buf);
    //stat 用来判断没有打开的文件 

    int fstat(int filedes,struct stat *buf);
    //fstat 用来判断打开的文件

    struct stat {
        dev_t st_dev; /* 设备 */
        ino_t st_ino; /* 节点 */
        mode_t st_mode; /* 模式 */
        nlink_t st_nlink; /* 硬连接 */
        uid_t st_uid; /* 用户 ID */
        gid_t st_gid; /* 组 ID */
        dev_t st_rdev; /* 设备类型 */
        off_t st_off; /* 文件字节数 */
        unsigned long st_blksize; /* 块大小 */
        unsigned long st_blocks; /* 块数 */
        time_t st_atime; /* 最后一次访问时间 */
        time_t st_mtime; /* 最后一次修改时间 */
        time_t st_ctime; /* 最后一次改变时间(指属性) */
    };
    /*
        S_ISREG(st_mode) 是否是一个常规文件.
        S_ISDIR(st_mode) 是否是一个目录 .
        S_ISCHR(st_mode) 是否是一个字符设备.
        S_ISBLK(st_mode) 是否是一个块设备 .
        S_ISFIFO(st_mode) 是否 是一个 FIFO文件.
        S_ISSOCK(st_mode) 是否是一个 SOCKET 文件.
    */

2.3目录文件操作

    #include <unistd.h>;
    char *getcwd(char *buffer,size_t size);
    /*
        提供一个 size 大小的 buffer,getcwd 把当前的路径考到 buffer 中.
        如果 buffer太小,函数会返回-1 和一个错误号.
    */
    #include <dirent.h>;
    #include <unistd.h>;
    #include <fcntl.h>;
    #include <sys/types.h>;
    #include <sys/stat.h>;
    int     mkdir(const char *path,mode_t mode);
    /*创建一个目录*/
    DIR     *opendir(const char *path);
    /*打开一个目录*/
    struct  dirent *readdir(DIR *dir);
    /*读一个打开的目录*/
    void    rewinddir(DIR *dir);
    /*重读目录*/
    off_t   telldir(DIR *dir);
    void    seekdir(DIR *dir,off_t off);
    /*telldir 和 seekdir 类似与 ftee 和 fseek 函数*/
    int     closedir(DIR *dir);
    /*关闭目录*/
    struct  dirent {
        long d_ino;
        off_t d_off;
        unsigned short d_reclen;
        char d_name[NAME_MAX+1]; /* 文件名称 */
    }

2.3管道文件

    #include<unistd.h>;
    int pipe(int fildes[2]);
    /*
        创建一个管道(通信缓冲区).
        当调用成功时,可以访问文件描述符 fildes[0],fildes[1].

        其中 fildes[0]是用来读的文件描述符,
        而 fildes[1]是用来写的文件描述符.
    */
    #include <unistd.h>;
    int dup2(int oldfd,int newfd);
    /*
        dup2 将用 oldfd 文件描述符来代替 newfd 文件描述符,同时关闭 
        newfd文件描述符.也就是说,所有向 newfd 操作都转到 oldfd 上面
    */

3.时间概念

3.1输出时间

    #include <time.h>
    time_t time(time_t * tloc);
    char*  ctime(const time_t *clock);
    /*
        time 函数返回从 1970 年 1 月 1 日 0 点以来的秒数.存储在 time_t 结构之中.不过这个函数的返回值对于我们来说没有什么实际意义.这个时候我们使用第二个函数将秒数转化为字符串.
        ctime这个函数的返回类型是固定的:一个可能值为. Thu Dec 7 14: 58: 59 2000 这个字符串的长度是固定的为 26.
    */

3.2测量时间

    #include <sys/time.h>;
    int gettimeofday(struct timeval *tv,struct timezone *tz);

    strut timeval {
        long tv_sec;  /* 秒数 */
        long tv_usec; /* 微秒数 */
    };
    /*gettimeofday 将时间保存在结构 tv 之中.
      tz 一般使用 NULL 来代替*/

3.3计时器

    /*
        ITIMER_REAL:    减少实际时间.到时的时候发出 SIGALRM 信号.
        ITIMER_VIRTUAL: 减少有效时间(进程执行的时间).产生 SIGVTALRM 信号.
        ITIMER_PROF:    减少进程的有效时间和系统时间(为进程调度用的时间).
        这个经常和上面一个使用用来计算系统内核时间和用户时间.产生 SIGPROF 信号.
    */
    #include <sys/time.h>;
    int getitimer(int which,struct itimerval *value);
    /*得到间隔计时器的时间值.保存在 value 中*/

    int setitimer(int which,struct itimerval *newval,
    struct itimerval *oldval);
    /*设置间隔计时器的时间值为 newval.并将旧值保存在 oldval 中. */

    struct itimerval {
        struct timeval it_interval;
        struct timeval it_value;
    }


    /*
        which     表示使用三个计时器中的哪一个.
        itimerval 结构中的 it_value 是减少的时间,当这个值为 0 的时候就发出相应的信号了. 
        然后设置为 it_interval 值.
    */

4.信号

4.1发出信号

    #include <sys/types.h>;
    #include <signal.h>;
    #include <unistd.h>;
    int kill(pid_t pid,int sig);
    /*kill 系统调用负责向进程发送信号 sig.*/
    /*
        如果 pid 是正数,那么向信号 sig 被发送到进程 pid.
        如果 pid 等于 0,那么信号 sig 被发送到所有和 pid 进程在同一个进程组的进程.
        如果 pid 等于-1,那么信号发给所有的进程表中的进程,除了最大的哪个进程号.
        如果 pid 由于-1,和 0 一样,只是发送进程组是-pid.
    */
    //最多的是第一个情况

    int raise(int sig);
    /*raise 系统调用向自己发送一个 sig 信号.相当于kill(getpid(),sig)*/

    unisigned int alarm(unsigned int seconds);
    /*在 seconds 秒后向自己发送一个 SIGALRM 信号*/

4.2信号操作

    #include <signal.h>;
    int sigemptyset(sigset_t *set);
    /*初始化信号集合 set,将 set 设置为空*/
    int sigfillset(sigset_t *set);
    /*初始化信号集合,只是将信号集合设置为所有信号的集合*/
    int sigaddset(sigset_t *set,int signo);
    /*将信号 signo 加入到信号集合之中*/
    int sigdelset(sigset_t *set,int signo);
    /*将信号从信号集合中删除*/
    int sigismember(sigset_t *set,int signo);
    /*查询信号是否在信号集合之中*/
    int sigprocmask(int how,const sigset_t *set,sigset_t *oset);
    /*最为关键的一个函数.在使用之前要先设置好信号集合 set.

    这个函数的作用是将指定的信号集合 set 加入到进程的信号阻塞集合之中去,如果提供了 oset 那么当前的进程信号阻塞集合将会保存在 oset 里面.

    参数 how 决定函数的操作方式:
        SIG_BLOCK:增加一个信号集合到当前进程的阻塞集合之中.
        SIG_UNBLOCK:从当前的阻塞集合之中删除一个信号集合.
        SIG_SETMASK:将当前的信号集合设置为信号阻塞集合.
    */
    #include <signal.h>;
    int sigaction(int signo,const struct sigaction *act,
    struct sigaction *oact);

    struct sigaction {
        void (*sa_handler)(int signo);
        void (*sa_sigaction)(int siginfo_t *info,void *act);
        sigset_t sa_mask;
        int sa_flags;
        void (*sa_restore)(void);
    }
    /*
        signo 要处理的信号,可以是任何的合法的信号.除(SIGKILL 和 SIGSTOP). 
        act 对这个信号进行如何处理的信息.
        oact 以前对这个函数的处理信息,一般为NULL不保存
        sa_handler 函数型指针,这个函数有一个参数.这个函数是要进行的信号操作的函数. 
        sa_sigaction,sa_restore 和 sa_handler 差不多的,只是参数不同,很少使用.
        sa_flags 用来设置信号操作的各个情况.一般设置为 0 
    */

    //使用时用sa_handler指向一个信号操作函数.sa_handler 有两个特殊的值: SIG_DEL 和 SIG_IGN.
    //SIG_DEL 是使用缺省的信号操作函数,而 SIG_IGN 是使用忽略该信号的操作函数

4.2其他操作

    #include <unistd.h>;
    #include <signal.h>;
    int pause(void);//挂起进程直到一个信号发生了.
    int sigsuspend(const sigset_t *sigmask);    
    //sigsuspend 也是挂起进程只是在调用的时候用 sigmask 取代当前的信号阻塞集合.
    #include <sigsetjmp>;
    int sigsetjmp(sigjmp_buf env,int val);
    void siglongjmp(sigjmp_buf env,int val);
    //类似goto 函数或者是 setjmp 和 longjmp 函数.
    //这两个信号跳转函数也可以实现程序的跳转, 可以从函数之中跳转到需要的地方.

5.消息管理

5.1无名信号量

    #include <semaphore.h>;
    int sem_init(sem_t *sem,int pshared,unsigned int value);
    /*创建一个信号灯,并初始化其值为 value.*/
    /*pshared 决定了信号量能否在几个进程间共享,Linux 还没有实现进程间共享信号灯,所以这个值只能够取 0.*/
    int sem_destroy(sem_t *sem);
    /*删除信号灯*/
    int sem_wait(sem_t *sem);
    /*将阻塞进程,直到信号灯的值大于 0.这个函数返回的时候自动的将信号灯的值的-1*/
    int sem_trywait(sem_t *sem);
    /*不阻塞的,当信号灯的值为 0 的时候返回 EAGAIN,表示以后重试.*/
    int sem_post(sem_t *sem);
    /*将信号灯的内容+1同时发出信号,唤醒等待的进程.*/
    int sem_getvalue(sem_t *sem);
    /*得到信号值*/

5.2SystemV信号量

    #include <sys/types.h>;
    #include <sys/ipc.h>;
    #include <sys/sem.h>;
    key_t ftok(char *pathname,char proj);
    //根据 pathname 和 proj 来创建一个关键字.
    int semget(key_t key,int nsems,int semflg);
    // 创建一个信号量,成功时返回信号的 ID.
    // key关键字,可以是ftok创建的或者IPC_PRIVATE表明由系统选用一个关键字. 
    // nsems 表明创建的信号个数.
    // semflg 是创建的权限标志,和创建文件的标志相同.
    int semctl(int semid,int semnum,int cmd,union semun arg);
    //对信号量进行一系列的控制.
    //semid 是要操作的信号标志,semnum 是信号的个数,cmd 是操作的命令.经常用的两个值是: SETVAL(设置信号量的值)和 IPC_RMID(删除信号灯).arg 是一个给 cmd 的参数.
    int semop(int semid,struct sembuf *spos,int nspos);
    /*对信号进行操作的函数.
    semid 是信号标志,
    spos 是一个操作数组表明要进行什么操作,
    nspos 表明数组的个数. 

    如果 sem_op 大于 0,那么操作将 sem_op 加入到信号量的值中,并唤醒等待信号增加的进程. 

    如果为 0,当信号量的值是 0 的时候,函数返回,否则阻塞直到信号量的值为 0. 

    如果小于 0,函数判断信号量的值加上这个负值.

    如果结果为 0 唤醒等待信号量为 0 的进程,
    如果小于 0 函数阻塞.
    如果大于 0,那么从信号量里面减去这个值并返回*/
    struct sembuf {
        short sem_num; /* 使用那一个信号 */
        short sem_op; /* 进行什么操作 */
        short sem_flg; /* 操作的标志 */
    };

5.3消息队列

    #include <sys/types.h>
    #include <sys/ipc.h>
    key_t ftok( const char * fname, int id );//id 1-255
    //当成功执行的时候,一个key_t值将会被返回,否则-1被返回。

    #include <sys/types.h>; 
    #include <sys/ipc.h>;
    #include <sys/msg.h>;
    int msgget(key_t key,int msgflg);
    //msgget 函数和 semget 一样,返回一个消息队列的标志

    int msgsnd(int msgid,struct msgbuf *msgp,int msgsz,int msgflg);
    int msgrcv(int msgid,struct msgbuf *msgp,int msgsz,
    long msgtype,int msgflg);
    //msgsnd 和 msgrcv 函数是用来进行消息通讯的

    int msgctl(Int msgid,int cmd,struct msqid_ds *buf);
    //msgctl 和 semctl 是对消息进行控制
    struct msgbuf {
        long msgtype; /* 消息类型 */
        ....... /* 其他数据类型 */
    }
    /*
        msgid 是接受或者发送的消息队列标志. 
        msgp 是接受或者发送的内容. 
        msgsz 是消息的大小. 
        结构 msgbuf 包含的内容是至少有一个为 msgtype. 
        其他的成分是用户定义的.

        对于发送函数 msgflg 指出缓冲区用完时候的操作. 
        接受函数指出无消息时候的处理.一般为 0. 
        接收函数 msgtype 指出接收消息时候的操作
    */

5.4共享内存

    #include <sys/types.h>;
    #include <sys/ipc.h>;
    #include <sys/shm.h>;
    int shmget(key_t key,int size,int shmflg);
    /*size大小,shmflg只要用0代替就可以*/
    void *shmat(int shmid,const void *shmaddr,int shmflg);
    /*用来连接共享内存的*/
    int shmdt(const void *shmaddr);
    /*断开共享内存*/
    int shmctl(int shmid,int cmd,struct shmid_ds *buf);
    //在使用一个共享内存之前调用 shmat 得到共享内存的开始地址,使用结束以后使用 shmdt 断开这个内存.

6.线程

6.1创建线程

    #include <pthread.h>;
    int pthread_create(pthread_t *thread,pthread_attr_t *attr,
    void *(*start_routine)(void *),void *arg);
    /*
        创建一个线程.
        thread 是用来表明创建线程的 ID,
        attr 指出线程创建时候的属性,用 NULL 来表明使用缺省性.
        start_routine 函数指针是线程创建成功后开始执行的函数.
        arg 是这个函数的唯一一个参数.表明传递给 start_routine 的参数. 
    */

6.2结束线程

    void pthread_exit(void *retval);
    /*
        pthread_exit 函数和 exit 函数类似用来退出线程.
        这个函数结束线程,释放函数的资源,并在最后阻塞,直到其他线程使用 
    */
    int pthread_join(pthread *thread,void **thread_return);
    /*
        pthread_join 函数等待它.然后将*retval 的值传递给**thread_
    return.
        由于这个函数释放所有的函数资源,所以 retval 不能够指向函数的局部变量. 
        pthread_join 和 wait 调用一样用来等待指定的线程. 
    */
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值