linux C语言 常用函数(系统调用等) 持续更新

系统调用是什么

在linux中,系统调用是指操作系统提供给用户程序调用的一组特殊接口。系统调用规划了用户访问内核的路径。

Linux C语言 文件部分系统调用

1.open()打开文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *path,int flag);
/*
返回值:成功时返回文件描述符,失败时返回-1
参数:
1.path:文件名的字符串地址
2.flag:文件打开模式信息(用位运算'|'连接)
O_CREAT:必要时创建文件
O_TRUNC:删除全部现有数据
O_APPEND:维持现有数据,保存到其后面
O_RDONLY:只读打开
O_WRONLY:只写打开
O_RDWR:读写打开
*/

2.close()关闭文件

#include <unistd.h>
int close(int fd);
/*
返回值:成功时返回0,失败时返回-1
参数:
fd:该文件的文件描述符
*/

3.mkdir()创建目录

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int mkdir(const char *pathname,mode_t mode);
/*
返回值:成功时返回0,失败时返回-1
参数:
1.pathname 目录路径字符串
2.mode_t (一个无符号八进制数)
S_IRUSR 00400 文件所有者具有可读权限
S_IWUSR 00200 文件所有者具有可写权限
S_IXUSR 00100 文件所有者具有可执行权限
S_IRGRP 00040 用户组具可读取权限
S_IWGRP 00020 用户组具可写入权限
S_IXGRP 00010 用户组具可执行权限
S_IROTH 00004 其他用户具可读取权限
S_IWOTH 00002 其他用户具可写入权限
S_IXOTH 00001 其他用户具可执行权限
S_IRWXU 00700 文件所有者具有可读写执行权限
*/

4.access()判断路径是否存在

#include <unistd.h>
int access(const char *pathname, int mode);
/*
access函数用来判断指定的文件或目录是否存在(F_OK),
已存在的文件或目录是否有可读(R_OK)、可写(W_OK)、可执行(X_OK)权限。
F_OK、R_OK、W_OK、X_OK这四种方式通过access函数中的第二个参数mode指定。
如果指定的方式有效,则此函数返回0,否则返回-1。
返回值:存在或者有权限时返回0,否则返回-1
参数:
1.pathname :文件或者目录路径
2.mode
F_OK 是否存在
R_OK 是否可读
W_OK 是否可写
X_OK 是否可执行
*/

5.fcntl()函数

#include fcntl(int fd, int cmd, ... /* int args*/ );
//返回值: 若成功,则依赖于cmd(见下);若出错,则返回-1

fcntl函数有5种功能

  • 复制一个已有的文件描述符(cmd=F_DUPFD或F_DUPFD_CLOEXEC)
  • 获取/设置文件描述符标志(cmd=F_GETFD或F_SETFD)
  • 获取/设置文件状态标志(cmd=F_GETFL或F_SETFL)
  • 获取/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN)
  • 获取/设置记录锁(cmd=F_GETLK/F_SETLK或F_SETLKW)

Linux C语言 命令系统调用

1.执行命令 system函数

#include <stdlib.h>
int system(const char * command)
//执行 dos(windows系统) 或 shell(Linux/Unix系统) 命令,参数字符串command为命令名。另,在windows系统下参数字符串不区分大小写。
//在windows系统中,system函数直接在控制台调用一个command命令
//在Linux/Unix系统中,system函数会调用fork函数产生子进程,由子进程来执行command命令,命令执行完后随即返回原调用的进程

Linux C语言 线程系统调用

1.创建线程pthread_create函数

#include <pthread.h>
int pthread_create(
pthread_t * restrict thread,
const pthread_attr_t * restrict attr,
void* (* start_routine)(void *),
void * restrict arg
);
/*
返回值:创建线程成功时,返回0;失败时,返回其他值。
参数:
thread:保存新线程ID的变量地址值
attr:用于传递线程属性的参数;传递NULL时,创建默认属性的线程
start_routine:相当于线程main函数的、在单独执行流中执行的函数地址值(函数指针)
arg:传给start_routine函数的参数的变量地址值。
*/

2.退出线程pthread_exit函数

#include <pthread.h>
void pthread_exit(void *retval);
/*
作用:将单个线程退出
参数:retval表示线程退出状态,通常传NULL。
*/

注意点:
1.return的作用是返回到函数的调用点,如果是main函数中的return,则代表该进程结束,并释放进程地址空间,所有线程都终止。对于其它函数的return,则直接返回到函数的调用点。exit和_exit函数会直接终止整个进程,导致所有线程结束。pthread_exit函数则会导致调用该函数的线程结束。所以,多线程环境中应尽量少用,或者不使用exit函数,取而代之使用pthread_exit函数,将单个线程退出。任何线程里exit导致进程退出,其他线程也结束,主控线程退出时不能return或exit。
2.另注意,pthread_exit或者return返回的指针(线程执行的函数用return或者pthread_exit结束线程时)所指向的内存单元必须是全局的或者是用malloc分配的,不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了(已经把线程栈上的内存回收),此时退出的这个线程函数所占据的栈空间可能又会被重新分配出去,因此其他线程再次使用这个返回的地址没有意义。

3.等待线程结束 pthread_join函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.获取线程id pthread_self()函数和gettid()函数

#include <pthread.h>
pthread_t pthread_self(void);
/*返回当前线程id*/

在这里插入图片描述

5.线程清理处理程序 pthread_cleanup_push/pop

 void pthread_cleanup_push(void (*routine)(void*),void *arg);
 //通过这个函数注册线程处理函数,即将routine放入栈中;arg为routine的参数;
 void pthread_cleanup_pop(int execute);
 //该函数的作用是:将pthread_cleanup_push放入栈中的函数指针取出,并让其执行;

但是要注意两种情况,
(1)当execute!=0的时候,线程清理函数一定会执行,因为是从栈中拿数据,所以处理函数的顺序会与pthread_cleanup_push注册的函数的顺序相反.
(2)当execute=0的时候,如果在pthread_cleanup_push和pthread_cleanup_pop之间没有调用pthread_exit()或有取消点的pthread_cancel()的时候,这时候仅仅是将函数指针从栈中取出来,而不会去执行.相反的话,即使execute=0还是会去

6.条件变量 pthread_cond_wait/signal

在这里插入图片描述
在这里插入图片描述

#include <pthread.h>

struct msg {            //结点
    struct msg *m_next;
    /*结点数据*/
};

struct msg *workq;      //消息队列头结点

pthread_cond_t qready = PTHREAD_COND_INITIALIZER;   //条件变量

pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;  //互斥锁

void process_msg()      //处理消息队列的消息
{
    struct msg *mp;
    while(1){
        pthread_mutex_lock(&qlock);         //上锁
        while(workq == NULL)                //队列为空
        {
            pthread_cond_wait(&qready,&qlock);  //释放锁,等待条件变量变为true(阻塞);条件变量true后,上锁,条件变量变为false。
        }
        //取出结点
        mp = workq;
        workq = workq->m_next;
        pthread_mutex_unlock(&qlock);
    }
}

void enqueue_msg(struct msg *mp)      //消息入队
{
    pthread_mutex_lock(&qlock);
    mp->m_next = workq;
    workq = mp;
    pthread_mutex_unlock(&qlock);
    pthread_cond_signal(&qready);       //队列有消息,条件变量true
}

C文件函数(封装了系统调用)

File 结构体

C语言的stdio.h头文件中,定义了用于文件操作的结构体FILE。这样,我们通过fopen返回一个文件指针(指向FILE结构体的指针)来进行文件操作。可以在stdio.h(位于visual studio安装目录下的include文件夹下)头文件中查看FILE结构体的定义,如下:

struct _iobuf {  
        char *_ptr;  
        int   _cnt;  
        char *_base;  
        int   _flag;  
        int   _file;  
        int   _charbuf;  
        int   _bufsiz;  
        char *_tmpfname;  
        };  
typedef struct _iobuf FILE;  

C程序用不同的FILE结构管理每个文件。程序员可以使用文件,但是不需要知道FILE结构的细节。实际上,FILE结构是间接地操作系统的文件控制块 (FCB)来实现对文件的操作的,如下图:
在这里插入图片描述
上面图中的_file实际上是一个描述符,作为进入打开文件表索引的整数 (文件描述符)。

文件结束符EOF

  • 我们知道,C++ 中可以通过cin,cin.get(),cin.getline(),getline() 等对字符串进行输入(若对这些输入模糊,可以阅读这篇文章:cin, cin.get(), cin.getline(), getline()的区别(直接看总结)),但它们都具有一定的限制,当遇到某种字符时便会结束读取,而有时候我们需要输入的文本中包含这些字符,该如何解决这个问题呢?
  • 这时我们就要用到文件结束符 EOF 来控制输入的结束,而在使用模拟 EOF 时则需要用到 cin.fail() 函数。
    Windows 系统中,我们可以通过 Ctrl + Z + Enter 来模拟 EOF 的输入,在 Unix 系统中可以通过 Ctrl + D + Enter 来模拟。
    此时,当我们模拟输入 EOF 后,函数 fail() 便会返回 true,我们就可以利用这一点作为判断条件,通过循环语句来进行输入,且在想要结束输入时模拟 EOF 的输入,即按下 Ctrl + Z +Enter 或 Ctrl + D + Enter 。
    如果想要清除 EOF 标记,则可以使用 cin.clear(),使输入能够继续。
  • 人们经常误认为 EOF 是从文件中读取的一个字符(牢记)。其实,EOF 不是一个字符,它被定义为是 int 类型的一个负数(比如 -1)。EOF 也不是文件中实际存在的内容。EOF 也不是只表示读文件到了结尾这一状态(这种状态可以用 feof() 来检测),它还能表示 I/O 操作中的读、写错误(通常可以用 ferror() 来检测)以及其它一些关联操作的错误状态

打开文件 fopen

FILE *fopen( const char *filename, const char *mode );   
  • 第一个参数是指向文件名字符串常量的指针类型;
  • 第二个参数指定文件打开的模式
    • r: 读取,如果文件不存在,函数调用失败
    • w: 为写入操作打开一个空文件。若文件不存在,则创建一个文件;若给定的文件已经存在,那么它的内容将被清空
    • a: 为写入操作打开文件。若文件不存在,则首先创建一个文件;若文件存在,那么在该文件结尾添加新数据,在写入数据之前,不会移除已有的EOF标记
    • r+:打开文件用于写入操作和读取操作,文件必须存在;
    • w+:写入和读取,其他同w;
    • a+:打开文件用于读取和添加操作,其他同a。

stdio.h(io头文件)

sprintf 往字符数组输入数据

int sprintf(char *buffer, const char *format, [argument]…)
参数:
(1)buffer:是char类型的指针,指向写入的字符串指针;

(2)format:格式化字符串,即在程序中想要的格式;

(3)argument:可选参数,可以为任意类型的数据;

函数返回值:buffer指向的字符串的长度;

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值