Linux 时间IO以及线程前导

Linux系统层次结构

调用c库会形成缓存,调用了磁盘。缓冲通常4096大小

进行系统调用时,每次都会调用磁盘。 

进程调用 

从磁盘中调用到内存中,为其分配磁盘空间。
T1、5个时间函数
1.滴答     clock(void);//启动到调用经过的滴答数
2.秒数时间 
    time(time_t *t);//标准时间到现在秒数
    ctime(time_t *t);//转化为字符串时间
    stime(time_t *t);//设置时间
    difftime(time_t t1,time_t t2);//计算时间差   
3.日历时间 
    localtime(time_t *t ); //转化为本地时间
    gmtime(time_t *t);//转化为格林尼治时间
    mktime(struct tm *p);//将UTC转化为time_t
4.微秒时间
    gettimeofday(struct timeval *tv);
    settimeofday(struct timeval *tv);
5.纳秒时间
   clock_gettime(CLOCK_REALTIME, &ts); 
对进程的查看流程:
nanosleep(const struct timespec *req, struct timespec *rem);
// 休眠 req 时间,如果被信号中断剩余的时间保存在 rem 中。
1.当前进程执行命令 ./a.out
2.另一个终端查询命令  ps aux|grep "a.out"
3. kill -SIGUSR1  进程ID  

IO模型

阻塞IO 如果数据不可用,则函数阻塞 cpu去干别的

非阻塞IO 如果数据可用,则得到数据,否则立即返回。cpu再次调用

IO复用

T2、同步IO与异步IO区别
同步IO为阻塞IO,每个IO会阻塞当前线程的执行。
异步IO为非阻塞IO,当IO完成后系统通知程序,期间不必等待。

同步I/O易于使用,适用于简单的应用程序或对并发性要求不高的场景。异步I/O适用于需要处理大量并发请求、需要高响应性和吞吐量的场景
T3、阻塞型IO与非阻塞IO区别
阻塞型IO若数据未准备就绪无法立即执行IO,调用IO的进程或线程会被阻塞,等待IO完成后的返回结果

非阻塞型IO在无法立即执行的情况下,立刻返回,并给出错误状态码,不会阻塞等待。

IO复用

select() //提供比阻塞型 IO 效率更高的 IO

poll()//可监控的文件数量比 select 更多

epoll()//比 poll 功能更强大,可以监测的文件更多
T4、分别使用 select、poll、epoll 监测标准输入、标准输出描述符,实现将输入的内容输出。

使用 select:

#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>

int main() {
    fd_set read_fds;
    struct timeval timeout;

    FD_ZERO(&read_fds);
    FD_SET(STDIN_FILENO, &read_fds);

    while (1) {
        timeout.tv_sec = 0;
        timeout.tv_usec = 0;

        int ready = select(STDIN_FILENO + 1, &read_fds, NULL, NULL, &timeout);
        if (ready == -1) {
            perror("select");
            exit(EXIT_FAILURE);
        }
        
        if (FD_ISSET(STDIN_FILENO, &read_fds)) {
            char input_data[256];
            fgets(input_data, sizeof(input_data), stdin);
            printf("Input: %s", input_data);
        }
    }

    return 0;
}

使用 poll:

#include <stdio.h>
#include <stdlib.h>
#include <poll.h>

int main() {
    struct pollfd fds[1];
    fds[0].fd = STDIN_FILENO;
    fds[0].events = POLLIN;

    while (1) {
        int ready = poll(fds, 1, 0);
        if (ready == -1) {
            perror("poll");
            exit(EXIT_FAILURE);
        }
        
        if (fds[0].revents & POLLIN) {
            char input_data[256];
            fgets(input_data, sizeof(input_data), stdin);
            printf("Input: %s", input_data);
        }
    }

    return 0;
}

使用 epoll:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/epoll.h>

int main() {
    int epollfd = epoll_create1(0);
    if (epollfd == -1) {
        perror("epoll_create1");
        exit(EXIT_FAILURE);
    }

    struct epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = STDIN_FILENO;
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, STDIN_FILENO, &event) == -1) {
        perror("epoll_ctl");
        exit(EXIT_FAILURE);
    }

    struct epoll_event events[1];
    while (1) {
        int ready = epoll_wait(epollfd, events, 1, 0);
        if (ready == -1) {
            perror("epoll_wait");
            exit(EXIT_FAILURE);
        }
        
        if (events[0].events & EPOLLIN) {
            char input_data[256];
            fgets(input_data, sizeof(input_data), stdin);
            printf("Input: %s", input_data);
        }
    }

    close(epollfd);

    return 0;
}
T5、在 day_time.c 模块实现一个设置、获取时间的接口利用 day_time.c 模块接口

写一个 Linux 命令行工具 mydate,用于设置和显示时间.
不能在程序中调用 Linux date命令。用法:
a. 只输入 mydate(),显示当前时间,不能用 asctime ()函数
b. 通过用命令行参数输入输入 mydate 年 月 日 时 分 秒,可以设置当前时间

time+localtime

mktime+stime

#include <time.h>

/* 获取当前时间 */
void get_current_time(struct tm *timeinfo) {
    time_t current_time = time(NULL);
    localtime_r(&current_time, timeinfo);
}

/* 设置时间 */
void set_time(struct tm *new_time) {
    time_t new_time_t = mktime(new_time);
    stime(&new_time_t);
}
#include <stdio.h>
#include <stdlib.h>
#include "day_time.c"

int main(int argc, char *argv[]) {
    if (argc == 1) {
        /* 只输入mydate,显示当前时间 */
        struct tm current_time;
        get_current_time(&current_time);
        printf("Current time: %d-%02d-%02d %02d:%02d:%02d\n", 
               current_time.tm_year + 1900, current_time.tm_mon + 1, current_time.tm_mday,
               current_time.tm_hour, current_time.tm_min, current_time.tm_sec);
    } else if (argc == 7) {
        /* 通过命令行参数设置时间 */
        struct tm new_time;
        new_time.tm_year = atoi(argv[1]) - 1900;
        new_time.tm_mon = atoi(argv[2]) - 1;
        new_time.tm_mday = atoi(argv[3]);
        new_time.tm_hour = atoi(argv[4]);
        new_time.tm_min = atoi(argv[5]);
        new_time.tm_sec = atoi(argv[6]);
        set_time(&new_time);
        printf("Time has been set successfully.\n");
    } else {
        printf("Invalid arguments.\n");
        printf("Usage:\n");
        printf("   mydate\n");
        printf("   mydate year month day hour minute second\n");
        return 1;
    }

    return 0;
}
T6、进程、线程、程序的区分
进程是程序的一次执行过程,包含了代码、数据和资源;程序是一组指令的集合,用于完成特定任务;线程是进程中的一部分,是执行任务的最小单位,多个线程共享进程的资源。
T7、fork()函数

创建新进程, 通过复制当前进程创建子进程

  • 在父进程中,fork()函数返回新创建的子进程的进程ID。

  • 在子进程中,fork()函数返回0。

  • 如果创建子进程失败,fork()函数返回-1。

    通过观察返回值来判断这个是啥进程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

S安东尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值