Linux系统编程(4)

news2024/12/26 12:53:19

分配数组

int *x, *y;
x = malloc(50*sizeof(int));
if(!x) {
    perror("malloc");
    return 1;
}

y = calloc(50, sizeof(int));
if (!y) {
    perror("calloc");
    return 1;
}

calloc会将所申请的内存全部填充0,malloc则不会。

调整内存分配的大小

#include <stdlib.h>
void* realloc(void* ptr, size_t size);

 

 创建匿名内存映射

#include <sys/mman.h>

void * mmap(void* start, size_t length, int port, int flags, int fd, off_t offset);
int munmap(void* start, size_t length);
void* p;
p = mmap(NULL,     // 此处无关紧要
        512*1024,  // 512KB
        PROT_READ | PROT_WRITE,  // 可供读取和写入
        MAP_ANONYMOUS | MAP_PRIVATE, // 匿名与私有
        -1,   // fd 忽略
        0);   // offset 忽略
if (p == MAP_FAILED)
    perror("mmap")
else

-- 第一个参数start设定为NULL,表示匿名映射的起始地址由内核自行决定,也可以指定非NULL的值,只要能够对齐页面,这样会导致移植性早到破坏。

-- 为了让映射可读可写,一般设定prot参数为PROT_READ | PROT_WRITE。

-- flags参数设定为MAP_ANONYMOUS | MAP_PRIVATE,

-- 当MAP_ANONYMOUS设定时,参数fd和offset会被忽略。

相比malloc之后再设置为memset,calloc会更加方便。

 映射/dev/zero

void* p;
int fd;
// 打开/dev/zero以备读取和写入
fd = open("/dev/zero", O_RDWR);
if (fd < 0) {
    perror("open");
    return 1;
}
// /dev/zero 的【0, page size】映射
p = mmap(NULL,  //此时无关紧要
        getpagesize(),   // 映射一个页面
        PROT_READ | PROT_WRITE,  // 可写可读
        MAP_PRIVATE, // 私有映射
        fd,  // 映射 /dev/zero 
        0);

if (p == MAP_FAILED) {
    
        perror("mmap");
        if (close(fd))
            perror("close");
        return -1;
}

//关闭 /dev/zero 
if (close(fd))
    perror("close");

将字符串复制到堆栈

alloca()常用于临时复制一个字符串
//想要复制 "song"
char* dup;

dup = alloca(strlen(song)+1);
strcpy(dup, song);
//操作dup
return;
#define _GNU_SOURCE
#include <string.h>
char* strdupa(const char* s);
char* strndupa(const char* s, size_t n);

设定字节

#include <string.h>
void* memset(void* s, int c, size_t n);

 比较字节

#include <string.h>
int memcmp(const void* s1, const void* s2, size_t n);

此函数会比较s1与s2的前n个字节,如果相等,返回0,如果s1<s2,返回<0的值,如果s1>s2,则返回.>0的值。

移动字节

#include <string.h>

void* memmove(void* dst, const void* src, size_t n);

 将src的前n个字节复制到dst,并返回dst.memmove()可以安全处理重叠区域。

#include <string.h>
void* memcpy(void* dst, const void* src, size_t n);

memcpy如同memmove,但是dst和src不可以重叠,如果重叠,则是未定义的。

#include <string.h>
void* memccpy(void* dst, const void* src, int c, size_t n);

memccpy()函数的行为如同memcpy(),但是如果此函数在src的前n个字节中发现了字节c,则停止复制,此函数会返回一个指针,指向dst中的c(如果找不到c,则指向NULL)之后的下一个字节。

最后使用mempcpy(),将数据复制到连续的内存位置。

#define _GNU_SOURCE
#include <string.h>

void* mempcpy(void* dst, const void* src, size_t n);

 mempcpy()函数的执行如同memcpy(),但是它会返回一个指针,指向复制的最后一个字节的下一个字节,如果有一组数据想要复制到连续的内存位置,这会很有用。

搜素字节

#include <string.h>
void* memchr(const void* s, int c, size_t n);

#define _GNU_SOURCE
#include <string.h>

void* memrchr(const void* s, int c, size_t n);

 

旋转字节

#define _GNU_SOURCE
#include <string.h>

void* memfrob(void* s, size_t n);

 信号列表

 等待任何一个信号

 下面的程序会停在pause()处,直到收到一个信号,才会从pause()返回。

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

// SIGINT 处理程序
static void SIGINT_handler(int signo) {
    printf("Caught SIGINT!\n");
    exit(EXIT_SUCCESS);
}


int main(int argc, char** argv) {
    /**
     * 将SIGINT_handler注册为我们用于处理SIGINT的信号处理程序
    */
    if (signal(SIGINT, SIGINT_handler) == SIG_ERR) {
        fprintf(stderr, "Cannot handle SIGINT!\n");
        exit(EXIT_FAILURE);
    }
    for(;;) {
        pause();
    }
    return 0;
}
//编译:gcc -o test test.c
执行./test
然后输入Ctrl+C
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

// SIGINT 处理程序
static void SIGINT_handler(int signo) {
    if (signo == SIGINT) {
        printf("Caught SIGINT!\n");
    } else if (signo == SIGTERM) {
        printf("Caught SIGTERM!\n");
    } else {
        fprintf(stderr, "Unexpected signal!\n");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}


int main(int argc, char** argv) {
    /**
     * 将SIGINT_handler注册为我们用于处理SIGINT的信号处理程序
    */
    if (signal(SIGINT, SIGINT_handler) == SIG_ERR) {
        fprintf(stderr, "Cannot handle SIGINT!\n");
        exit(EXIT_FAILURE);
    }
    /**
     * 将SIGINT_handler注册为我们用于处理SIGTERM的信号处理程序
    */
    if (signal(SIGTERM, SIGINT_handler) == SIG_ERR) {
        fprintf(stderr, "Cannot handle SIGTERM!\n");
        exit(EXIT_FAILURE);
    }
    /**
     * SIGPROF 的行为重置为默认值
    */
    if (signal(SIGPROF, SIG_DFL) == SIG_ERR) {
        fprintf(stderr, "Cannot handle SIGPROF!\n");
        exit(EXIT_FAILURE);
    }

    /**
     * 忽略SIGHUP
    */
    if (signal(SIGHUP, SIG_IGN) == SIG_ERR) {
        fprintf(stderr, "Cannot handle SIGHUP!\n");
        exit(EXIT_FAILURE);
    }
    for(;;) {
        pause();
    }
    return 0;
}

发送一个信号

#include <sys/types.h>
#include <signal.h>

int kill(pid_t pid, int signo);

 给自己发送一个信号

#include <signal.h>
int raise(int signo);

给整个进程组传送一个信号

除了kill,可以使用

#include <signal.h>
int killpg(int pgrp, int signo);

等效于
kill (-pgrp, signo);

保证可重入函数

 

 信号集

#include <signal.h>
int sigemptyset(sigset_t * set);
int sigfillset(sigset_t* set);
int sigaddset(sigset_t* set, int signo);
int sigdelset(sigset_t* set, int signo);
int sigismember(const sigset_t* set, int signo);

linux还提供以下非标准的函数:

#define _GNU_SOURCE
#include <signal.h>

int sigisemptyset(sigset_t* set);
int sigorset(sigset_t * dest, sigset_t* left, sigset_t* right);
int sigandset(sigset_t* dest, sigset_t* left, sigset_t* right);

时间的数据结构

#include <sys/time.h>
struct timeval {
    time_t tv_sec;    //seconds
    susecondes_t tv_usec;  //microsecondes
};


#include <time.h>
struct timespec {
    time_t tv_sec;   //seconds
    long tv_nsec;   //nanosecondes
};

获取当前时间

#include <time.h>

time_t time(time_t* t);

time_t t;
printf("current time: %ld\n", (long)time(&t));
printf("the same value: %ld\n", (long)t);


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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1126020.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

驱动开发4 使用字符设备驱动的分步实现编写LED驱动(LED亮灯)

一、思维导图 二、通过字符设备驱动的分步实现编写LED驱动&#xff0c;另外实现特备文件和设备的绑定 应用程序 test.c #include<stdlib.h> #include<stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include…

嵌入式linux系统中设备树基础知识

笔记整理自百问网正点原子 前言 之前分享的笔记&#xff1a;【Linux笔记】总线设备驱动模型中在platform_device部分有简单说明描述设备有两种方法&#xff1a;一种是使用platform_device结构体来指定&#xff1b;另一种是使用设备树来描述。 本篇笔记我们就来简单地学习一下…

系列三、其他流

一、缓冲流 1.1、概述 缓冲流也叫高效流&#xff0c;是对最基本的FileInputStream、FileOutputStream、FileReader、FileWriter的增强&#xff0c;所以也是4个流&#xff0c;按照数据类型分为如下种类 字节缓冲流&#xff1a;BufferedInputStream、BufferedOutputStream字符…

一、C++入门

1 C关键字 C语言中有32个关键字&#xff0c;而在C中有63个关键字。 当前我们不对关键字进行具体了解&#xff0c;等后续要用到的时候再学习该如何使用。 2 命名空间 在C和C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称将都…

pr加马赛克怎么加?

PR是常用的视频剪辑和处理软件&#xff0c;能够对视频进行一些美化、编辑处理等&#xff0c;大家都知道视频处理一个比较常见的操作那就是添加马赛克。那么&#xff0c;pr加马赛克能不能操作呢&#xff1f;其实是很简单的处理方式&#xff0c;下边&#xff0c;我们就一起看看如…

Redis实战之年会抽奖

前言&#x1f50d; 上一篇&#xff1a;Redis实战之微博点赞 本篇涉及相关命令&#xff1a;Sadd、Spop 示例基于SpringBoot 2.7.14 Sadd Sadd 命令将一个或多个成员元素加入到集合中&#xff0c;已经存在于集合的成员元素将被忽略。假如集合 key 不存在&#xff0c;则创建一…

小程序 this.setData is not a function解决办法

报错是因为函数中有 wx.showModal 或者 wx.request等请求&#xff0c;放在请求体里面时会报错。 this组用域的问题&#xff0c;success函数包实际上是一个闭包&#xff0c;无法通过this来直接setData 怎样修改呢&#xff1f; 我们需要将当&#xff0c;前对象赋予给一个新的对…

Flappy bird项目

一、功能分析 1、小鸟自动向右滑行 2、按下空格小鸟上升&#xff0c;不按下落 3、显示小鸟需要穿过的管道 4、管道自动左移和创建 5、小鸟和管道碰撞&#xff0c;游戏结束 6、技术 7、 项目框图 8、Ncurses 1&#xff09;创建窗口界面&#xff0c;移动光标&#xff0c;产…

Linux系统CH347应用—I2C功能

Linux/安卓系统使用CH347转接I2C功能有三种应用方式&#xff1a; 1. 使用CH34X_MPHSI_Master总线驱动为系统扩展原生I2C Master&#xff0c;此方式无需进行单独的应用层编程&#xff1b; 2. 使用CH341PAR_LINUX字符设备驱动&#xff0c;此方式需要配合使用厂商提供的库文件&a…

数据要素安全流通:挑战与解决方案

文章目录 数据要素安全流通&#xff1a;挑战与解决方案一、引言二、数据要素安全流通的挑战数据泄露风险数据隐私保护数据跨境流动监管 三、解决方案加强数据安全防护措施实施数据隐私保护技术建立合规的数据跨境流动机制 四、数据安全流通的未来趋势01 数据价值与产业崛起02 多…

CUDA学习笔记(十四) Constant Memory

转载至https://www.cnblogs.com/1024incn/tag/CUDA/ CONSTANT MEMORY constant Memory对于device来说只读但是对于host是可读可写。constant Memory和global Memory一样都位于DRAM&#xff0c;并且有一个独立的on-chip cache&#xff0c;比直接从constant Memory读取要快得多…

iPhone开发--Xcode15下载iOS 17.0.1 Simulator Runtime失败解决方案

爆句粗口&#xff0c;升级后公司网络下载iOS 17.0.1 Simulator Runtime一直出错&#xff0c;每次出错后都得重新开始下载&#xff0c;oh&#xff0c;f**k。上一次在在家里的网络升级成功。 解决办法一&#xff1a; 进入网址&#xff1a;https://developer.apple.com/download…

【产品设计】B端SaaS产品原则

B端产品设计并不是一个人的事情&#xff0c;往往是一个团队共同完成的。在整个团队中&#xff0c;会涉及到四个环节&#xff1a;需求环节、设计环节、研发环节和运营环节。在这些环节中&#xff0c;需要遵循一些原则&#xff0c;共同推动整个产品建设。 本文针对产品的需求环节…

Pyside6 QMenuBar

Pyside6 QMenuBar QMenuBar使用QMenuBar常用函数QMenuBar常用信号QMenuBar添加菜单项QMenuBar添加图标QMenuBar添加菜单点击事件 Pyside6 QMenuBar类提供了一个水平菜单栏&#xff0c;更多关于QMenuBar的使用可以参考下面的文档。 https://doc.qt.io/qtforpython-6/PySide6/QtW…

Java中,如何在字符串后面补全空格

笔者在字符串有多个空格如何截取一文中写道了如何对字符串的多个空格进行截取&#xff0c;那么反过来&#xff0c;在调用三方接口&#xff0c;需要按照对方的报文格式&#xff0c;给左右的属性进行填充空格&#xff0c;以便对齐格式 例如这样&#xff1a; 那么我们应该怎么做…

《红蓝攻防对抗实战》六.常规反弹之利用NC在windows系统执行反弹shell

目录 一.利用NC工具在windows系统执行反弹shell 1. Windows正向连接shell 2.Windows反向连接shell 前文推荐&#xff1a; 《红蓝攻防对抗实战》一. 隧道穿透技术详解《红蓝攻防对抗实战》二.内网探测协议出网之TCP/UDP协议探测出网《红蓝攻防对抗实战》三.内网探测协议出网…

SpringBoot项目中使用MybatisPlus

MybatisPlus的优点 使用时注意事项: 首先需要在spring boot启动类中添加MapperScan注解&#xff0c;扫描Mapper文件夹。 并且在POM文件引入坐标的时候不要同时引入Mybatis和Mybatis-Plus的坐标。容易出现版本差异不兼容。 日志配置 由于SQL的执行是不可见的&#xff0c;所以…

高通平台USB 2.0和USB 3.0接口充电器识别原理

1 BC 1.2 1.1 充电器类型探测 1&#xff09;DCD&#xff1a;DP上有150mV&#xff08; 10uA x 15K欧姆下拉电阻&#xff09;的电压&#xff0c;DM上电压为0 2&#xff09;Primary Det&#xff08;DP发起检测DM&#xff09;&#xff1a; - DP上加载0.6V电压&#xff0c;DM上电压为…

Plonky2:最好的SNARKs和STARKs

1. 引言 Plonky2为Polygon团队2022年1月发起的项目。其定位为ZKP证明系统。 开源代码实现见&#xff1a; https://github.com/0xPolygonZero/plonky2&#xff08;Rust 汇编&#xff09; Plonky2可解锁当今2大主流ZKP类型——SNARKs和STARKs的扩容优势。 每个ZKP证明系统都有…

Selenium自动化测试中常见的异常详解

概要 开发人员在编写代码时总是会考虑到不同的应用场景&#xff0c;但也可能会出现实现效果不如预期的情况。同样的原则也适用于测试代码&#xff0c;编写测试代码的主要目的是测试现有产品的功能、发现错误并使产品100%无错误。 有句话说得好&#xff1a;"真相总是比小说…