LinuxC函数使用总结

LinuxC函数

前置知识

文件描述符

  • 在进程的PCB中,有专门存储文件描述符的位置。

  • 在PCB中,有一个*files 的指针,这个指针指向一个名叫 files_struct 的指针数组,这里这个指针数组里存储的就是指向不同文件的指针,既然是一个数组,那就可以通过下标进行数组元素的访问,所以,这里数组的下标的值,就是文件描述符的值。

  • 我们如果在进程中打开文件的时候,系统就会在这个进程的files_struct中添加进对应的文件的指针,然后返回这个文件指针对应的文件描述符,也就是这个文件的下标。我们在进行文件读写操作的时候,如果我们调用的是系统提供的读写操作接口的话,就势必需要使用文件描述符进行操作

  • 文件描述符在分配的时候,并不是按照你打开的文件的顺序进行分配的,而是,从目前能分配的最小的文件描述符进行分配,比如说:你如果关闭了这个进程的标准输入和标准输出,这两个文件的文件描述符就会被释放,然后,再次打开一个新的文件的时候,就会给这个文件分配一个0的文件描述符,占有标准输入的文件描述符的位置。

文件描述符

1.pipe2(int pipefd[2], int flags)

传入数组两个元素被赋予管道两端的文件描述符,通过描述符进行读写操作。

pipe用于与fork出的子进程通信,父子进程各选一个端口close掉,就变成了单向pipe,并且是同步的

fd[0]:读管道,fd[1]:写管道。

管道.PNG

2.dup2(int oldfd, int newfd, int flags)

作用:使得新fd与旧fd操作相同的文件,例如dup2(-1,1),会使得对标准输出流的输入进入/dev/null

fd 0,1,2分别对应标准输入,标准输出,错误流

3.setsid()

  • 前置知识

session

img

举个例子,使用xshell登录服务器就是创建了一个session

通过这个shell session启动一个进程,这个进程作为父进程启动了其他子进程,那么就相当于启动了一个进程组

我们同时在后台启动多个进程组,就会得到如上图所示的情况。

setsid

setsid 会创建一个新的 session,它的目的是让进程在后台执行命令,实现方式就是让命令进程运行在一个新的与终端脱离的 session 中。看下面的示例

root@dggphisprb19134:/usr1/zhd/learn/learn-c/afltest# setsid sleep 1000
root@dggphisprb19134:/usr1/zhd/learn/learn-c/afltest# ps -o pid,ppid,pgid,sid,tty,comm
  PID  PPID  PGID   SID TT       COMMAND
 7784 26122  7784 26122 pts/4    ps
26122 26055 26122 26122 pts/4    bash
root@dggphisprb19134:/usr1/zhd/learn/learn-c/afltest# ps aux | grep sleep
root      7567  0.0  0.0  16140   864 ?        S    14:36   0:00 sleep 180
root      7578  0.0  0.0  16140   812 ?        S    14:36   0:00 sleep 180
root      7589  0.0  0.0  16140   980 ?        S    14:37   0:00 sleep 180
root      7594  0.0  0.0  16140   824 ?        S    14:37   0:00 sleep 180
root      7595  0.0  0.0  16140   828 ?        S    14:37   0:00 sleep 180
root      7779  0.0  0.0  16140   864 ?        Ss   14:38   0:00 sleep 1000
root      7790  0.0  0.0  18840  1004 pts/4    S+   14:38   0:00 grep --color=auto sleep

这时候发现sleep进程被系统1号进程systemd收养了

systemd-+-acpid
        |.... 中间其他进程省略
        |
        |-sleep
        |-smbd---2*[smbd]
        |-snapd---7*[{snapd}]
        |-spesservice---9*[{spesservice}]

close(int fd)

close就是让当前fd不再绑定具体文件(失效)

官方解释如下 :

int close(int fd);

DESCRIPTION
       close() closes a file descriptor, so that it no longer refers to any file and may be reused.  Any record locks (see fcntl(2)) held on the file it was associated with, and
       owned by the process, are removed (regardless of the file descriptor that was used to obtain the lock).

       If fd is the last file descriptor referring to the underlying open file description (see open(2)), the resources associated with the open file description are  freed;  if
       the descriptor was the last reference to a file which has been removed using unlink(2), the file is deleted.

execv(const char* file, char * const argv[])

execv的作用:将新程序代码加载(拷贝)到子进程的内存空间,替换掉原有的与父进程一模一样的代码和数据,让子进程空间运行全新的程序

在Linux中使用exec函数族主要有以下两种情况:

a. 当进程认为自己不能再为系统和用户做出任何贡献时,就可以调用任何exec 函数族让自己重生。

b. 如果一个进程想执行另一个程序,那么它就可以调用fork函数新建一个进程,然后调用任何一个exec函数使子进程重生。

样例如下:

代码

// exectest.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    printf("parent process start!\n");
    int fk_id = fork();
    if (!fk_id) {
        execv("./hello",NULL);
        printf("i am fork process\n");
    }
    printf("i am parent process\n") ;
}
#include <stdio.h>
int main() {
    printf("\nhello world!\n"); 
    exit(0);
}
  • 编译
root@dggphisprb19134:/usr1/zhd/learn/learn-c/afltest# gcc exectest.c -o ext
root@dggphisprb19134:/usr1/zhd/learn/learn-c/afltest# gcc hello.c -o hello
  • 执行
root@dggphisprb19134:/usr1/zhd/learn/learn-c/afltest# ./ext 
parent process start!
i am parent process
root@dggphisprb19134:/usr1/zhd/learn/learn-c/afltest# 
hello world!

可以看出来,fork进程的 “i am fork process”打印语句未执行,因为fork进程已被替换为hello进程.

setitimer()

函数原型

setitimer(int which, const struct itimerval * new_value, struct itimerval *old_value)

itimerval结构体,相当于一个配置器

           struct itimerval {
               struct timeval it_interval; /* Interval for periodic timer */
               struct timeval it_value;    /* Time until next expiration */
           };
        //子结构,有秒和毫秒两档
           struct timeval {
               time_t      tv_sec;         /* seconds */
               suseconds_t tv_usec;        /* microseconds */
           };

搭配setitimer()函数使用,通过信号机制做出反应

static int count = 0;
void set_timer()
{
    struct itimerval itv;
    itv.it_value.tv_sec = 3;    //timer start after 3 seconds later
    itv.it_value.tv_usec = 0;
    itv.it_interval.tv_sec = 1;
    itv.it_interval.tv_usec = 0;
    setitimer(ITIMER_REAL,&itv,NULL);
}

void signal_handler(int m)
{
    count ++;
    printf("%d\n",count);
}

int main()
{
    signal(SIGALRM,signal_handler);
    set_timer();
    while(count < 10);
    exit(0);
    return 0;
}

这段代码实现的功能:3秒钟后启动定时器。然后每隔1秒钟向终端打印count的递增值,当count到10时程序退出

getitimer

函数原型

int getitimer(int which, struct itimerval *curr_value);

功能:传入itimerval指针作为返回值入参,获得当前timer的拷贝.

dup2

函数原型

int dup2(int oldfd, int newfd) 

作用:将newfd描述符重定向到oldfd,此后对newfd的操作,都体现在oldfd上

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,616评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,020评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,078评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,040评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,154评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,265评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,298评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,072评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,491评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,795评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,970评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,654评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,272评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,985评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,815评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,852评论 2 351

推荐阅读更多精彩内容