linux-IO-进程-线程(相关函数)

相关代码资源:xLinux: linux,网络编程阶段代码

1、IO

库函数

错误处理:

1. errno

errno是一个全局变量(在大多数实现中),用于报告系统调用的错误。当系统调用(如文件操作、内存分配等)失败时,errno会被设置为一个特定的错误码,以指示发生了什么类型的错误。errno的定义位于<errno.h>(或<stdlib.h>在某些系统上)头文件中。

注意 :由于errno是全局的,它可能会被多个线程同时访问,因此在多线程程序中需要特别注意其线程安全性。许多现代系统提供了线程局部存储(TLS)版本的errno,以避免这种问题。

使用示例

|---|---------------------------------------------------------|
| | #include <stdio.h> |
| | #include <stdlib.h> |
| | #include <errno.h> |
| | |
| | int main() { |
| | FILE *fp = fopen("nonexistentfile.txt", "r"); |
| | if (fp == NULL) { |
| | printf("Error opening file: %s\n", strerror(errno)); |
| | } |
| | return 0; |
| | } |

2. perror

perror函数用于打印一条描述最近发生的错误的消息到标准错误(stderr)。它会自动使用errno的值来确定要打印的错误消息。perror的原型定义在<stdio.h>头文件中。

使用示例

|---|--------------------------------------------------|
| | #include <stdio.h> |
| | #include <stdlib.h> |
| | |
| | int main() { |
| | FILE *fp = fopen("nonexistentfile.txt", "r"); |
| | if (fp == NULL) { |
| | perror("Error opening file"); |
| | } |
| | return 0; |
| | } |

在这个例子中,如果文件打开失败,perror会打印类似于"Error opening file: No such file or directory"的消息(具体消息取决于errno的值和系统的本地化设置)。

3. strerror

strerror函数用于将errno的值转换为对应的错误消息字符串。它接受一个errno值作为参数(尽管在实际使用中,你通常会传递errno宏本身,因为它指向当前的错误码),并返回一个指向错误消息字符串的指针。这个字符串是静态分配的,因此每次调用strerror时,之前的返回值可能会被覆盖。strerror的原型定义在<string.h>头文件中。

使用示例 (已在前面的errno示例中展示):

|---|--------------------------------------------------------|
| | printf("Error opening file: %s\n", strerror(errno)); |

文件

输入

1. fgetc

  • 函数原型 : int fgetc(FILE *stream);
  • 头文件 : #include <stdio.h>
  • 返回值: 成功时返回读取的字符(作为无符号字符转换为int),遇到文件结束符(EOF)或错误时返回EOF。
  • 功能 : 从指定的文件流stream中读取下一个字符。

2. fgets

  • 函数原型 : char *fgets(char *str, int n, FILE *stream);
  • 头文件 : #include <stdio.h>
  • 返回值 : 成功时返回指向str的指针,遇到文件结束符(EOF)或读取错误时返回NULL。
  • 功能 : 从指定的文件流stream中读取最多n-1个字符(为了留出空间给字符串结束符\0),直到遇到换行符、文件结束符或读取了n-1个字符为止。

3. fread

  • 函数原型 : size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
  • 头文件 : #include <stdio.h>
  • 返回值 : 成功读取的元素个数,可能小于请求的数量(nmemb)。
  • 功能 : 从指定的文件流stream中读取数据到ptr指向的数组中。每次读取size字节,共读取nmemb次。

4. fscanf

  • 函数原型 : int fscanf(FILE *stream, const char *format, ...);
  • 头文件 : #include <stdio.h>
  • 返回值: 成功匹配并赋值的输入项数,遇到文件结束符或读取错误时可能小于预期。
  • 功能 : 根据指定的格式字符串format从文件流stream中读取数据,并将读取的数据存储到后续参数指定的变量中。

5. getc

  • 函数原型 : int getc(FILE *stream);
  • 头文件 : #include <stdio.h>
  • 返回值: 成功时返回读取的字符(作为无符号字符转换为int),遇到文件结束符(EOF)或错误时返回EOF。
  • 功能 : 类似于fgetc,从指定的文件流stream中读取下一个字符。

6. gets(已废弃)

  • 函数原型 : char *gets(char *str);
  • 头文件 : #include <stdio.h>(但不建议使用,因为它不安全)
  • 返回值 : 成功时返回指向str的指针,遇到文件结束符(EOF)或读取错误时返回NULL。
  • 功能: 从标准输入读取一行文本,直到遇到换行符或EOF,但不包括换行符。由于可能导致缓冲区溢出,该函数已被废弃。

7. scanf

  • 函数原型 : int scanf(const char *format, ...);
  • 头文件 : #include <stdio.h>
  • 返回值: 成功匹配并赋值的输入项数,遇到文件结束符或读取错误时可能小于预期。
  • 功能 : 根据指定的格式字符串format从标准输入读取数据,并将读取的数据存储到后续参数指定的变量中。

8. getchar

  • 函数原型 : int getchar(void);
  • 头文件 : #include <stdio.h>
  • 返回值: 成功时返回读取的字符(作为无符号字符转换为int),遇到文件结束符(EOF)或错误时返回EOF。
  • 功能: 从标准输入读取下一个字符。
输出

1. fputc

  • 函数原型 : int fputc(int char, FILE *stream);
  • 返回值 : 成功时返回写入的字符(转换为unsigned char后再转换为int),失败时返回EOF
  • 头文件 : #include <stdio.h>
  • 功能 : 将一个字符(实际上是以int形式传递的)写入到指定的文件流stream中。

2. fputs

  • 函数原型 : int fputs(const char *s, FILE *stream);
  • 返回值 : 成功时返回非负值,失败时返回EOF
  • 头文件 : #include <stdio.h>
  • 功能 : 将字符串s(不包括结尾的空字符\0)写入到指定的文件流stream中。

3. fwrite

  • 函数原型 : size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
  • 返回值: 成功写入的元素个数。
  • 头文件 : #include <stdio.h>
  • 功能 : 将ptr指向的数组中的数据写入到指定的文件流stream中。每次写入size字节,共写入nmemb次。

4. fprintf

  • 函数原型 : int fprintf(FILE *stream, const char *format, ...);
  • 返回值: 成功写入的字符数(不包括结尾的空字符),出错时返回负值。
  • 头文件 : #include <stdio.h>
  • 功能 : 根据指定的格式字符串format向文件流stream写入数据。

5. putc

  • 函数原型 : int putc(int char, FILE *stream);
  • 返回值 : 成功时返回写入的字符(转换为unsigned char后再转换为int),失败时返回EOF
  • 头文件 : #include <stdio.h>
  • 功能 : 类似于fputc,将一个字符(以int形式传递)写入到指定的文件流stream中。

6. puts

  • 函数原型 : int puts(const char *s);
  • 返回值 : 成功时返回非负值,失败时返回EOF
  • 头文件 : #include <stdio.h>
  • 功能 : 将字符串s(包括结尾的空字符\0,但puts会在输出后自动添加一个换行符\n)写入到标准输出。

7. printf

  • 函数原型 : int printf(const char *format, ...);
  • 返回值: 成功写入的字符数(不包括结尾的空字符),出错时返回负值。
  • 头文件 : #include <stdio.h>
  • 功能 : 根据指定的格式字符串format向标准输出写入数据。

8. putchar

  • 函数原型 : int putchar(int char);
  • 返回值 : 成功时返回写入的字符(转换为unsigned char后再转换为int),失败时返回EOF
  • 头文件 : #include <stdio.h>
  • 功能 : 将一个字符(以int形式传递)写入到标准输出。
打开:

fopen

  • 函数原型FILE *fopen(const char *filename, const char *mode);
  • 头文件#include <stdio.h>
  • 功能 :根据指定的文件名(filename)和模式(mode)打开一个文件,并返回一个指向FILE的指针,该指针用于后续的文件操作。如果打开文件失败,则返回NULL
  • 模式(mode
    • "r":以只读方式打开文件。该文件必须存在。
    • "w":以只写方式打开文件。如果文件存在,则长度被截断为零,即该文件内容会消失。如果文件不存在,则创建新文件。
    • "a":以追加方式打开文件。如果文件存在,写入的数据会被追加到文件尾。如果文件不存在,则创建新文件。
    • "r+":以读/写方式打开文件。该文件必须存在。
    • "w+":以读/写方式打开文件。如果文件存在,则文件长度被截断为零,即该文件内容会消失。如果文件不存在,则创建新文件。
    • "a+":以读/写方式打开文件,数据将被追加到文件尾。如果文件不存在,则创建新文件。
关闭

fclose

  • 函数原型int fclose(FILE *stream);
  • 头文件#include <stdio.h>
  • 功能 :关闭一个由fopenfreopenfdopen函数打开的文件流(stream)。如果成功,返回0;如果失败,返回EOF
  • 注意 :使用完文件后,应及时关闭它,以释放相关资源。fclose会刷新缓冲区中的输出数据(如果有的话),关闭文件,并释放与stream相关联的所有资源。
定位:

fseek

  • 函数原型int fseek(FILE *stream, long offset, int whence);
  • 功能fseek 函数用于重新定位文件流(stream)中的位置指针。它根据whence参数指定的起点和offset参数指定的偏移量来移动位置指针。
  • 参数
    • FILE *stream:指向FILE对象的指针,该对象标识了要操作的文件流。
    • long offset:从whence指定的位置开始计算的偏移量(以字节为单位)。
    • int whence:起始位置,它是一个宏定义,可以是以下值之一:
      • SEEK_SET:文件的开头。
      • SEEK_CUR:当前位置。
      • SEEK_END:文件的末尾。
  • 返回值 :成功时返回0,失败时返回非零值。

ftell

  • 函数原型long ftell(FILE *stream);
  • 功能ftell 函数用于获取当前文件流(stream)中的位置指针的位置(即当前读写位置)。
  • 参数
    • FILE *stream:指向FILE对象的指针,该对象标识了要查询的文件流。
  • 返回值 :成功时返回当前位置(以字节为单位),失败时返回-1L

目录

打开目录
  • 函数DIR *opendir(const char *name);
  • 头文件<dirent.h>
  • 功能 :打开指定的目录name,并返回一个指向DIR的指针,该指针用于后续的目录读取操作。如果打开失败,返回NULL
切换目录
  • 函数int chdir(const char *path);
  • 头文件<unistd.h>
  • 功能 :将当前工作目录更改为path指定的目录。成功时返回0,失败时返回-1
读取目录
  • 函数struct dirent *readdir(DIR *dirp);
  • 头文件<dirent.h>
  • 功能 :读取dirp指向的目录流中的下一个目录项。如果到达目录末尾或发生错误,则返回NULL
创建目录
  • 函数int mkdir(const char *pathname, mode_t mode);
  • 头文件<sys/stat.h><sys/types.h>(可能需要)
  • 功能 :创建名为pathname的新目录,其权限位由mode指定。成功时返回0,失败时返回-1
删除目录
  • 函数int rmdir(const char *pathname);
  • 头文件<unistd.h>
  • 功能 :删除名为pathname的空目录。成功时返回0,失败时返回-1
获取绝对路径
  • 函数char *getcwd(char *buf, size_t size);
  • 头文件<unistd.h>
  • 功能 :将当前工作目录的绝对路径复制到buf指向的数组中。如果bufNULL,则函数分配足够的内存来存储路径(这种情况需要手动释放内存)。成功时返回指向buf的指针,失败时返回NULL
定位(在目录流中)
  • 函数long int telldir(DIR *dirp);

  • 头文件<dirent.h>

  • 功能 :返回目录流dirp的当前位置(一个相对于目录开头的偏移量)。这可以用于在读取目录时记录位置。

  • 函数void seekdir(DIR *dirp, long int loc);

  • 头文件<dirent.h>

  • 功能 :将目录流dirp的位置设置为loc,该位置是之前通过telldir函数获得的。

  • 函数void rewinddir(DIR *dirp);

  • 头文件<dirent.h>

  • 功能 :将目录流dirp的位置重置为流的开头。

关闭目录
  • 函数int closedir(DIR *dirp);
  • 头文件<dirent.h>
  • 功能 :关闭由opendir函数打开的目录流dirp。成功时返回0,失败时返回-1

系统调用

文件操作

open
  • 原型int open(const char *pathname, int flags, ...);
  • 头文件<fcntl.h><sys/types.h>, <sys/stat.h>, <unistd.h>
  • 返回值:成功时返回非负整数(文件描述符),失败时返回-1并设置errno。
  • 功能:打开或创建一个文件,并返回一个文件描述符用于后续的读写操作。
read
  • 原型ssize_t read(int fd, void *buf, size_t count);
  • 头文件<unistd.h>
  • 返回值:成功时返回读取的字节数,当到达文件末尾时返回0,失败时返回-1并设置errno。
  • 功能:从文件描述符指向的文件中读取数据到缓冲区。
write
  • 原型ssize_t write(int fd, const void *buf, size_t count);
  • 头文件<unistd.h>
  • 返回值:成功时返回写入的字节数,失败时返回-1并设置errno。
  • 功能:向文件描述符指向的文件中写入数据。
close
  • 原型int close(int fd);
  • 头文件<unistd.h>
  • 返回值:成功时返回0,失败时返回-1并设置errno。
  • 功能:关闭一个打开的文件描述符。
lseek
  • 原型off_t lseek(int fd, off_t offset, int whence);
  • 头文件<unistd.h>
  • 返回值:成功时返回新的文件偏移量(相对于文件开头),失败时返回(off_t)-1并设置errno。
  • 功能:移动文件描述符的读写位置。

文件属性

stat
  • 原型int stat(const char *pathname, struct stat *buf);
  • 头文件<sys/stat.h>
  • 返回值:成功时返回0,失败时返回-1并设置errno。
  • 功能:获取文件的状态信息。
lstat
  • 原型int lstat(const char *pathname, struct stat *buf);
  • 头文件<sys/stat.h>
  • 返回值:成功时返回0,失败时返回-1并设置errno。
  • 功能 :类似于stat,但当参数为符号链接时,返回链接本身的信息。

用户和组信息

getpwuid
  • 原型struct passwd *getpwuid(uid_t uid);
  • 头文件<sys/types.h>, <pwd.h>, <unistd.h>
  • 返回值 :成功时返回指向passwd结构的指针,失败时返回NULL。
  • 功能:通过用户ID获取用户信息。
getgrgid
  • 原型struct group *getgrgid(gid_t gid);
  • 头文件<sys/types.h>, <grp.h>, <unistd.h>
  • 返回值 :成功时返回指向group结构的指针,失败时返回NULL。
  • 功能:通过组ID获取组信息。

文件锁

fcntl
  • 原型int fcntl(int fd, int cmd, ... /* arg */ );
  • 头文件<fcntl.h>
  • 返回值 :取决于cmd参数,通常成功时返回非负值,失败时返回-1并设置errno。
  • 功能:文件控制操作,包括设置/获取文件锁等。

cmd参数(与文件锁相关):

  • F_GETLK:获取文件锁的信息。
  • F_SETLK:设置文件锁,但不会阻塞。
  • F_SETLKW:设置文件锁,如果发生冲突则阻塞。
lockf
  • 原型int lockf(int fd, int cmd, off_t len);
  • 头文件<unistd.h>
  • 返回值:成功时返回0,失败时返回-1并设置errno。
  • 功能:对文件的一部分进行加锁或解锁操作。

时间处理:

1. time()

函数原型time_t time(time_t *tloc);

头文件<time.h>

功能 :获取当前时间(自1970年1月1日(称为Unix纪元)以来的秒数)。如果tloc不是NULL,该函数还会将这个时间值存储在tloc指向的位置。

返回值:成功时返回当前时间(以秒为单位),失败时返回-1。

2. ctime()

函数原型char *ctime(const time_t *timep);

头文件<time.h>

功能 :将time_t类型的时间(通常是time()函数的返回值)转换为本地时间的字符串表示形式。返回的字符串包含了日期和时间,格式通常是"Wed Jun 30 21:49:08 1993\n"。

返回值 :指向一个静态分配的字符串的指针,该字符串包含了转换后的时间和日期。由于这个字符串是静态分配的,因此连续调用ctime()可能会导致之前的返回值被覆盖。

3. localtime()

函数原型struct tm *localtime(const time_t *timep);

头文件<time.h>

功能 :将time_t类型的时间(自Unix纪元以来的秒数)转换为本地时间(考虑时区),并以struct tm结构体的形式返回。

返回值 :指向一个struct tm类型的静态分配对象的指针,该对象包含了转换后的时间信息。和ctime()一样,由于返回的是静态分配的内存,连续调用可能会覆盖之前的结果。

4. strftime()

函数原型size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);

头文件<time.h>

功能 :根据format指定的格式,将struct tm结构体中的时间信息格式化为字符串,并存储在s指向的数组中。max参数指定了s数组的大小,以避免溢出。

返回值 :如果成功,返回存储在s中的字符数(不包括终止的空字符);如果发生错误,返回0。

5. struct tm

定义struct tm是一个结构体,用于表示时间信息。它通常包含以下成员(但可能因系统而异):

  • int tm_sec; // 秒(0-59)
  • int tm_min; // 分(0-59)
  • int tm_hour; // 小时(0-23)
  • int tm_mday; // 一个月中的第几天(1-31)
  • int tm_mon; // 月份(0-11,其中0表示1月)
  • int tm_year; // 年份,自1900年起
  • int tm_wday; // 一周中的第几天(0-6,其中0表示星期日)
  • int tm_yday; // 一年中的第几天(0-365,其中0表示1月1日)
  • int tm \_isdst; // 夏令时标志

进程相关:

1. getpid()

  • 头文件<unistd.h>
  • 参数:无
  • 返回值:成功时,返回当前进程的进程ID(PID),一个非负整数。如果出错(虽然这种情况非常罕见),理论上可能会返回-1,但通常不会。
  • 功能:获取当前进程的PID。

2. getppid()

  • 头文件<unistd.h>
  • 参数:无
  • 返回值:成功时,返回当前进程的父进程ID(PPID),一个非负整数。如果出错(同样非常罕见),可能会返回-1。
  • 功能:获取当前进程的父进程的PID。

3. fork()

  • 头文件<unistd.h>
  • 参数:无
  • 返回值
    • 在父进程中,返回新创建的子进程的PID。
    • 在子进程中,返回0。
    • 如果出错,返回-1,并设置errno以指示错误。
  • 功能:创建一个新的进程,称为子进程,它是调用进程的副本。

4. system()

  • 头文件<stdlib.h>
  • 参数:一个指向以null结尾的字符串的指针,该字符串包含了要执行的shell命令。
  • 返回值
    • 命令的终止状态。如果命令成功执行,并且返回了0,则system()通常也返回0。
    • 如果命令无法被执行,或者system()调用失败,则返回-1。注意,system()的返回值与shell命令的退出状态可能不完全相同,因为system()还会返回shell本身的退出状态。
  • 功能:执行一个shell命令,并等待命令执行完成。

5. exec函数族

这些函数用于在当前进程中加载并运行一个新程序,替换当前进程的映像。一旦exec函数成功执行,当前进程的映像就被新程序替换,因此exec函数不会返回给调用者。

  • 头文件<unistd.h>
execl
  • 参数 :程序路径,参数列表(以NULL结尾)。
  • 返回值 :如果execl成功,则不会返回;如果失败,则设置errno并返回-1(但实际上这个返回值不会被看到,因为进程映像已经被替换)。
  • 功能:执行指定路径的程序,并传递参数列表。
execlp
  • 参数 :程序名(在PATH环境变量指定的目录中搜索),参数列表(以NULL结尾)。
  • 返回值功能 :与execl相同,但程序名不需要完整路径。
execv
  • 参数 :程序路径,参数数组(以NULL指针结尾)。
  • 返回值功能 :与execl相同,但参数通过数组传递。
execvp
  • 参数 :程序名(在PATH环境变量指定的目录中搜索),参数数组(以NULL指针结尾)。
  • 返回值功能 :与execv相同,但程序名不需要完整路径。
execvpe
  • 参数 :程序名(在PATH环境变量指定的目录中搜索),参数数组(以NULL指针结尾),环境变量数组(以NULL指针结尾)。
  • 返回值功能 :与execvp相同,但允许为新程序指定环境变量。注意,并非所有系统都提供execvpe函数。

6. wait()

  • 头文件<sys/wait.h>(在某些系统中,也可能需要<sys/types.h>
  • 参数 :通常是一个指向int的指针,用于存储结束的子进程的终止状态;也可以是WAIT_ANY(在waitpid中更常见,但wait通常不使用此值)。
  • 返回值
    • 成功时,返回结束的子进程的PID。
    • 如果出错,返回-1,并设置errno以指示错误。
    • 如果wait()被信号中断,并且没有指定WNOHANG选项(wait函数本身不接受此选项,但waitpid接受),则行为未定义(但在实践中,它可能会返回-1并设置errnoEINTR)。然而,wait函数通常会在等待子进程时阻塞,直到有子进程结束。
  • 功能 :等待一个子进程结束,并获取其终止状态。如果有多个子进程,则wait会等待任意一个子进程结束。

waitpid():

在 C 语言中,waitpid() 函数的原型通常如下(以 POSIX 标准为例):

|---|-------------------------------------------------------|
| | #include <sys/wait.h> |
| | #include <sys/types.h> |
| | |
| | pid_t waitpid(pid_t pid, int *status, int options); |

参数
  • pid:指定要等待的子进程的 PID(进程ID)。这个参数有几个特殊的值:

    • -1:等待任何一个子进程结束。这相当于 wait() 函数的行为,但 waitpid() 提供了更多的选项。
    • 0:等待与调用进程属于同一进程组的任何子进程。
    • > 0:等待其 PID 与参数相等的子进程。
    • < -1:等待其组 ID 等于参数绝对值且与调用进程属于同一进程组的任何子进程。
  • status :指向整数的指针,用于接收子进程的退出状态。如果此参数不是 NULLwaitpid() 将把子进程的退出状态写入它所指向的内存位置。这个状态信息可以通过宏函数(如 WIFEXITED(), WEXITSTATUS(), WIFSIGNALED(), WTERMSIG(), WIFSTOPPED(), WSTOPSIG())来解读。

  • options :控制 waitpid() 的行为。这个参数可以是 0 或以下一个或多个常量的按位或组合:

    • WNOHANG:即使没有任何子进程结束,也立即返回。此时,如果 status 不是 NULL 且没有子进程结束,则返回 0;如果有子进程结束,则返回该子进程的 PID。
    • WUNTRACED:如果子进程被停止(例如,由于收到 SIGSTOPSIGTSTPSIGTTINSIGTTOU 信号),也返回其状态。默认情况下,waitpid() 只返回已终止的子进程的状态。
返回值
  • 成功时,返回等待的子进程的 PID。
  • 如果 WNOHANG 被设置且没有子进程满足条件,则返回 0。
  • 如果发生错误,则返回 -1,并设置 errno 以指示错误的原因。

守护进程创建:

1. 创建子进程:fork()

  • 功能fork()函数用于创建一个新的进程,称为子进程,它是当前进程的一个副本。
  • 返回值
    • 在父进程中,fork()返回新创建的子进程的PID。
    • 在子进程中,fork()返回0。
    • 如果出错,则返回-1。

2. 新建会话:setsid()

  • 功能setsid()函数用于创建一个新的会话(session),并使调用进程成为该会话的会话首进程(session leader)。同时,调用进程还会脱离任何控制终端(如果有的话)。
  • 返回值
    • 成功时,返回会话ID(通常等于调用进程的PID)。
    • 如果调用进程已经是会话首进程,则返回-1,并设置errno
    • 如果出错,也返回-1,并设置errno

3. 改变工作目录:chdir()

  • 功能chdir()函数用于改变当前工作目录到指定的目录。
  • 参数:一个指向以null结尾的字符串的指针,该字符串指定了新的工作目录的路径。
  • 返回值
    • 成功时,返回0。
    • 如果出错,返回-1,并设置errno

守护进程通常会改变其工作目录到根目录(/),以避免占用可卸载的文件系统。

4. 设置文件模式创建掩码:umask()

  • 功能umask()函数用于设置进程的文件模式创建掩码。这个掩码会影响随后创建的文件的权限。
  • 参数:一个新的文件模式创建掩码,通常是八进制数。
  • 返回值
    • 成功时,返回之前的文件模式创建掩码。
    • 如果出错,返回-1,但这种情况很少见。

守护进程通常会设置掩码以确保新创建的文件具有适当的权限。

5. 关闭文件描述符

守护进程需要关闭它从父进程继承的所有不必要的文件描述符,以避免潜在的资源泄露或安全问题。这通常通过遍历文件描述符表并关闭每个描述符来实现,但首先需要知道文件描述符表的大小。

  • getdtablesize() :这个函数用于获取进程的文件描述符表的大小(即可以打开的最大文件描述符数)。然而,需要注意的是,getdtablesize()函数并不是POSIX标准的一部分,而且在许多现代系统上可能不可用或已被废弃。在这些系统上,你可能需要依赖于其他方法(如sysconf(_SC_OPEN_MAX))来获取这个值,或者简单地关闭你已知不需要的文件描述符。

进程组

  • setpgid(pid_t pid, pid_t pgid)
    • setpgid函数用于设置指定进程(pid)的进程组ID。如果pid为0,则调用进程(即当前进程)的进程组ID被设置为pgid。如果pgid等于0,则调用进程的进程组ID被设置为调用进程的进程ID。这个函数通常用于创建新的进程组或改变现有进程的进程组。
  • 注意 :这里没有直接列出获取当前进程所属进程组ID的函数,但可以通过调用getpgid(0)来获取调用进程所在进程组的ID,其中0代表当前进程。

会话

  • getsid(pid_t pid)
    • getsid函数用于获取指定进程(pid)所在会话的会话ID。会话ID是分配给会话中每个进程的唯一标识符。如果pid是0,则函数返回调用进程所在会话的会话ID。
  • setsid()
    • setsid函数用于创建一个新的会话,并成为该会话的会话首进程(session leader)。调用此函数的进程会成为新会话的唯一成员,并且与之前的控制终端(如果有的话)脱离。此外,调用进程的进程组ID和会话ID会被设置为与该进程的进程ID相同,该进程成为新进程组的组长。这个函数通常用于创建守护进程(daemon)或需要脱离控制终端的程序。

系统日志:

1. openlog 函数

openlog 函数用于打开与 syslog 守护进程的连接,并可选地设置日志消息的标识。虽然调用 syslog 之前不强制要求调用 openlog,但使用 openlog 可以定制日志消息的一些属性。

函数原型

|---|--------------------------------------------------------------|
| | void openlog(const char *ident, int option, int facility); |

  • ident:用于每条日志消息前的标识字符串。如果为 NULL,则使用程序名。
  • option:控制日志记录行为的选项,如 LOG_CONSLOG_NDELAYLOG_NOWAITLOG_ODELAYLOG_PERRORLOG_PID
  • facility:用于指定日志消息的来源或类别(如系统守护进程、用户级别消息等)。

2. syslog 函数

syslog 函数用于向系统日志守护进程发送消息。

函数原型

|---|-------------------------------------------------------|
| | void syslog(int priority, const char *format, ...); |

  • priority:日志消息的优先级,由设施(facility)和级别(level)两部分组成,通过位或操作组合。
  • format:格式字符串,类似于 printf 的格式字符串。
  • ...:与 format 对应的参数列表。

3. closelog 函数

closelog 函数用于关闭与 syslog 守护进程的连接。不过,在程序正常结束时,这个调用通常是可选的,因为系统会在程序退出时自动清理资源。

函数原型

|---|------------------------|
| | void closelog(void); |

系统日志优先级;

进程的终止:

正常终止

  1. 主函数 return
    • 当主函数(通常是 main 函数)执行到 return 语句时,程序会正常结束。返回给操作系统的值通常用于指示程序的退出状态(成功或某种形式的错误)。
  2. 调用 exit
    • exit 函数用于正常终止程序,并可以指定一个退出状态给操作系统。它会执行一些清理工作,包括调用所有已注册的 atexit 函数,关闭所有打开的文件描述符(如果有的话),清空并关闭 stdoutstderr 缓冲区(但请注意,这并不意味着它会"清空" stdout 的内容,而是确保所有缓冲的输出都被刷新到终端或文件中)。
  3. 调用 _exit
    • _exit 函数也用于终止程序,但它不执行任何清理操作,如关闭文件描述符或调用 atexit 函数。它直接退出程序,并将控制权返回给操作系统,因此不会清空 stdout 缓冲区。这通常用于在程序已经严重损坏或处于不安全状态时快速退出。

异常终止

  1. kill 命令
    • kill 命令用于向指定的进程发送信号。如果发送的信号是终止信号(如 SIGTERM 或 SIGKILL),则会导致进程异常终止。SIGTERM 请求进程终止,但允许它进行清理操作;而 SIGKILL 强制立即终止进程,不允许进行任何清理。
  2. 主动异常终止 abort
    • abort 函数用于生成一个 SIGABRT 信号,该信号通常用于指示程序中的严重错误,如断言失败。接收到 SIGABRT 信号后,程序会异常终止,并可能生成一个核心转储文件(取决于操作系统的配置),用于调试。
  3. 另一个进程或硬件信号终止
    • 除了 kill 命令发送的信号外,程序还可能因为接收到来自其他进程的信号或硬件事件(如非法内存访问)而异常终止。这些信号包括但不限于 SIGINT(通常由 Ctrl+C 触发)、SIGSEGV(段错误)、SIGFPE(浮点异常)等。接收到这些信号后,程序通常会立即终止,除非有信号处理函数被注册来捕获并处理这些信号。

线程相关:

线程库:NPTL

1. 线程创建:pthread_create

|---|----------------------------------------------------------------------|
| | int pthread_create(pthread_t *thread, const pthread_attr_t *attr, |
| | void *(*start_routine) (void *), void *arg); |

  • 功能 :创建一个新线程,该线程执行由start_routine指定的函数,arg作为该函数的参数。
  • 参数
    • thread:指向pthread_t类型的指针,用于存储新线程的标识符。
    • attr:指向线程属性对象的指针,可以指定线程的各种属性,如堆栈大小、调度策略等。如果为NULL,则使用默认属性。
    • start_routine:新线程将要执行的函数。
    • arg:传递给start_routine函数的参数。
  • 返回值:成功时返回0,失败时返回错误码。

2. 查看当前线程ID:pthread_self

|---|---------------------------------|
| | pthread_t pthread_self(void); |

  • 功能:返回调用线程的线程ID。
  • 返回值:调用线程的线程ID。

3. 等待线程结束:pthread_join

|---|------------------------------------------------------|
| | int pthread_join(pthread_t thread, void **retval); |

  • 功能 :等待指定的线程结束。如果retval不为NULL,则线程的返回值将被存储在retval指向的位置。
  • 参数
    • thread:要等待的线程的线程ID。
    • retval:用于存储线程返回值的指针的地址。如果不需要,可以设置为NULL。
  • 返回值:成功时返回0,失败时返回错误码。

4. 分离线程:pthread_detach

|---|-----------------------------------------|
| | int pthread_detach(pthread_t thread); |

  • 功能 :将指定的线程设置为"分离"状态,这样当线程结束时,其资源会自动释放,而不需要其他线程来调用pthread_join
  • 参数
    • thread:要设置为分离状态的线程的线程ID。
  • 返回值:成功时返回0,失败时返回错误码。

5. 线程退出:pthread_exit

|---|------------------------------------|
| | void pthread_exit(void *retval); |

  • 功能:终止调用线程的执行。如果线程创建了子线程,并且这些子线程尚未被分离或等待,则这些子线程将不会被终止。
  • 参数
    • retval:线程的返回值,其他线程可以通过pthread_join获取。
  • 注意 :一旦调用了pthread_exit,线程将不再执行任何代码。

6. 取消线程:pthread_cancel

|---|-----------------------------------------|
| | int pthread_cancel(pthread_t thread); |

  • 功能:向指定的线程发送取消请求。线程是否响应取消请求取决于其取消状态和取消类型。
  • 参数
    • thread:要取消的线程的线程ID。
  • 返回值:成功时返回0,失败时返回错误码。
  • 注意 :线程可以通过设置取消状态和取消类型来忽略取消请求,或者通过调用pthread_testcancel来检查是否有取消请求并响应它。

7.手动添加取消点

1. pthread_testcancel

功能
pthread_testcancel 函数用于测试调用线程是否应该被取消。如果线程被设置了取消状态(即,其他线程对该线程调用了 pthread_cancel),并且该线程没有禁用取消(通过 pthread_setcancelstate),则 pthread_testcancel 会导致线程被取消,就像执行了一个异步取消请求一样。

头文件

|---|------------------------|
| | #include <pthread.h> |

返回值

  • 成功时,该函数不返回(因为线程被取消)。
  • 如果线程没有被取消,则该函数正常返回。

参数

无参数。

注意事项

  • 线程应定期调用 pthread_testcancel 以确保能够及时响应取消请求。
  • 取消是协作的,意味着线程必须主动检查取消状态(通过 pthread_testcancel)或执行可能被取消的点(如某些库函数)。

8. 资源清理栈 (pthread_cleanup_pushpthread_cleanup_pop)

功能

资源清理栈用于在线程取消或退出时自动执行清理操作(如释放资源、关闭文件等)。pthread_cleanup_push 用于将清理函数压入栈中,而 pthread_cleanup_pop 用于从栈中移除清理函数,并可选择性地执行它。

头文件

|---|------------------------|
| | #include <pthread.h> |

pthread_cleanup_push 返回值

  • 无返回值(宏定义,非函数)。

pthread_cleanup_pop 返回值

  • 成功时返回 0。
  • 出错时返回错误码。

参数

  • pthread_cleanup_push(void (*routine)(void *), void *arg)
    • routine:指向清理函数的指针。
    • arg:传递给清理函数的参数。
  • pthread_cleanup_pop(int execute)
    • execute:如果非 0,则执行栈顶的清理函数;如果为 0,则不执行。

注意事项

  • 清理函数应设计为可重入的,因为可能在多线程环境中被调用。
  • 使用 pthread_cleanup_pushpthread_cleanup_pop 时,通常将 pthread_cleanup_push 放在代码块的开始,pthread_cleanup_pop 放在结束(无论是正常退出还是通过异常路径)。
  • 如果在 pthread_cleanup_pop 调用之前线程被取消,则栈上所有未执行的清理函数都将被执行。
  • 清理函数不应调用任何可能导致线程取消的函数,因为这可能导致死锁或未定义行为。

同步互斥机制:

同步 - 无名信号量

头文件<semaphore.h>(注意,在某些系统中可能需要链接实时库,如-lrt

sem_init

  • 功能:初始化一个未命名的信号量。
  • 参数
    • sem:指向信号量结构的指针。
    • pshared:如果非0,信号量将在进程间共享;如果为0,信号量仅在当前进程的线程间共享。
    • value:信号量的初始值。
  • 返回值:成功时返回0;失败时返回-1,并设置errno。

sem_wait

  • 功能:等待(阻塞)信号量的值大于0。如果信号量的值为0,则调用线程将被阻塞,直到信号量的值大于0。操作成功后,信号量的值减1。
  • 参数sem:指向信号量结构的指针。
  • 返回值:成功时返回0;失败时返回-1,并设置errno。

sem_post

  • 功能:增加信号量的值。如果信号量的值从0增加到1,则可能唤醒一个等待该信号量的线程。
  • 参数sem:指向信号量结构的指针。
  • 返回值:成功时返回0;失败时返回-1,并设置errno。

同步 - 有名信号量

头文件<sys/sem.h>,但注意,在现代Linux系统中,通常推荐使用POSIX信号量(即无名信号量),因为semgetsemopsemctl等函数是System V信号量的API,它们较老且不如POSIX信号量灵活。

semget

  • 功能:创建一个新的信号量集或访问一个已存在的信号量集。
  • 参数
    • key:用于创建新信号量集的唯一标识符。
    • nsems:信号量集中的信号量数量。
    • semflg:控制信号量集创建的标志。
  • 返回值:成功时返回信号量集的标识符;失败时返回-1,并设置errno。

semop

  • 功能:对信号量集中的信号量执行操作。
  • 参数
    • semid:信号量集的标识符。
    • sops:指向sembuf结构的数组,指定了要执行的操作。
    • nsopssops数组中元素的数量。
  • 返回值:成功时返回0;失败时返回-1,并设置errno。

semctl

  • 功能:用于对信号量集执行各种控制操作,如获取信号量的值、设置信号量的值、初始化信号量集等。
  • 参数
    • semid:信号量集的标识符。
    • semnum:信号量集中的信号量编号(从0开始)。
    • cmd:要执行的控制命令。
    • arg:根据cmd的不同,这个参数可以是不同的类型,如信号量的新值、指向union semun的指针等。
  • 返回值 :根据cmd的不同,返回值也有所不同。对于大多数命令,成功时返回0;失败时返回-1,并设置errno。

互斥

头文件<pthread.h>

pthread_mutex_init

  • 功能:初始化一个互斥锁。
  • 参数
    • mutex:指向互斥锁变量的指针。
    • attr:用于指定互斥锁属性的指针,如果为NULL,则使用默认属性。
  • 返回值:成功时返回0;失败时返回错误码。

pthread_mutex_lock

  • 功能:尝试对互斥锁加锁。如果互斥锁已被锁定,则调用线程将被阻塞,直到互斥锁被解锁。
  • 参数mutex:指向互斥锁变量的指针。
  • 返回值:成功时返回0;失败时返回错误码。

pthread_mutex_unlock

  • 功能:对互斥锁进行解锁。
  • 参数mutex:指向互斥锁变量的指针。
  • 返回值:成功时返回0;失败时返回错误码。

pthread_mutex_destroy

  • 功能:销毁一个互斥锁。在销毁之前,必须确保互斥锁是未锁定的状态。
  • 参数mutex:指向互斥锁变量的指针。
  • 返回值:成功时返回0;失败时返回错误码。

通信机制:

system V :

命令:ipcs ,,ipcrm

  • 函数原型key_t ftok(const char *pathname, int proj_id);
  • 头文件<sys/ipc.h>

参数说明

  • pathname :指向文件路径的指针。这个文件通常是项目中的一个已知文件,但它不需要实际存在,但必须是唯一的,以便在不同的项目或实例中生成不同的键。不过,在大多数实际使用中,为了确保键的唯一性和稳定性,通常会指定一个确实存在的文件。
  • proj_id:一个8位(1字节)的整数,用于进一步区分同一路径下的不同键。这个值通常是项目的唯一标识符,但在实际应用中,它可以是任何非零的整数值。
返回值
  • 如果成功,ftok函数返回一个唯一的键(key_t类型)。
  • 如果失败,返回-1,并设置errno以指示错误。可能的错误包括EACCES(调用进程对pathname没有读权限)、ENOENT(pathname指定的文件或目录不存在)、ENOMEM(没有足够的内存来执行操作)和EINVAL(pathname不指向一个文件或目录)。

管道

有名管道
  • mkfifo
    • 头文件<sys/stat.h><fcntl.h>
    • 功能:创建一个有名管道。
    • 参数
      • pathname:管道的文件名。
      • mode:管道文件的权限,类似于open函数的mode参数。
    • 返回值:成功时返回0;失败时返回-1,并设置errno。
匿名管道
  • pipe函数
    • 头文件<unistd.h>
    • 功能:创建一个匿名管道,用于父子进程或相关进程间的通信。
    • 参数
      • filedes:指向一个包含两个文件描述符的数组,第一个用于读,第二个用于写。
    • 返回值:成功时返回0;失败时返回-1,并设置errno。

消息队列

  • msgget
    • 头文件<sys/ipc.h><sys/msg.h>
    • 功能:创建或访问一个消息队列。
    • 参数
      • key:用于创建或访问消息队列的键。
      • msgflg:控制消息队列创建和访问的标志。
    • 返回值:成功时返回消息队列的标识符;失败时返回-1,并设置errno。
  • msgsnd
    • 功能:向消息队列发送消息。
    • 参数
      • msqid:消息队列的标识符。
      • msgp:指向消息缓冲区的指针。
      • msgsz:消息的大小(不包括消息类型字段)。
      • msgflg:控制消息发送的标志。
    • 返回值 :成功时返回0;失败时返回-1,并设置errno。
  • msgrcv
    • 功能:从消息队列接收消息。
    • 参数
      • msqid:消息队列的标识符。
      • msgp:指向消息缓冲区的指针。
      • msgsz:消息缓冲区的最大大小。
      • msgtyp:请求的消息类型。
      • msgflg:控制消息接收的标志。
    • 返回值:成功时返回接收到的消息的实际字节数;失败时返回-1,并设置errno。
  • msgctl
    • 功能:执行消息队列的控制操作,如删除队列。
    • 参数
      • msqid:消息队列的标识符。
      • cmd:要执行的控制命令。
      • buf:指向msqid_ds结构的指针,用于某些命令。
    • 返回值:成功时返回0;失败时返回-1,并设置errno。

共享内存

  • shmget
    • 功能:创建或访问一个共享内存段。
    • 参数
      • key:用于创建或访问共享内存段的键。
      • size:共享内存段的大小。
      • shmflg:控制共享内存段创建和访问的标志。
    • 返回值:成功时返回共享内存段的标识符;失败时返回-1,并设置errno。
  • shmat
    • 功能:将共享内存段连接到进程的地址空间。
    • 参数
      • shmid:共享内存段的标识符。
      • shmaddr:建议的附加地址(通常为NULL)。
      • shmflg:控制附加操作的标志。
    • 返回值:成功时返回共享内存段附加到进程地址空间的地址;失败时返回(void *)-1,并设置errno。
  • shmdt
    • 功能:断开共享内存段与进程的连接。
    • 参数
      • shmaddr:共享内存段附加到进程地址空间的地址。
    • 返回值:成功时返回0;失败时返回-1,并设置errno。
  • shmctl
    • 功能:执行共享内存段的控制操作,如删除共享内存段。
    • 参数
      • shmid:共享内存段的标识符。
      • cmd:要执行的控制命令。
      • buf:指向shmid_ds结构的指针,用于某些命令。
    • 返回值:成功时返回0;失败时返回-1,并设置errno。

信号---(阻塞未决等信息另一篇有提到这里不详解)

  • kill
    • 头文件<signal.h>
    • 功能:向进程发送信号。
    • 参数
      • pid:接收信号的进程的PID。
      • sig:要发送的信号。
    • 返回值:成功时返回0;失败时返回-1,并设置errno。
  • raise
    • 功能:向当前进程发送信号。
    • 参数
      • sig:要发送的信号。
    • 返回值:成功时返回0;失败时返回非0值,并设置errno。
  • abort
    • 功能:导致程序异常终止,并向进程发送SIGABRT信号。
    • 参数:无。
    • 返回值:不返回。
更改信号的默认行为:
signal 函数
返回值
  • 成功时返回之前的信号处理函数指针(如果成功查询)或0(如果成功设置)。
  • 失败时返回SIG_ERR,并设置errno以指示错误。
头文件
  • <signal.h>
功能
  • 设置或查询与特定信号相关联的处理函数。
参数
  • int signum:要处理的信号编号。
  • void (*handler)(int):指向新信号处理函数的指针,或者SIG_IGN(忽略信号)、SIG_DFL(恢复信号的默认处理行为)等特殊值。

|---|------------------------------------------|
| | #include <signal.h> |
| | #include <stdio.h> |
| | #include <stdlib.h> |
| | |
| | void signal_handler(int signum) { |
| | printf("Caught signal %d\n", signum); |
| | // 清理代码... |
| | exit(signum); |
| | } |
| | |
| | int main() { |
| | // 设置SIGINT信号的处理函数 |
| | signal(SIGINT, signal_handler); |
| | |
| | // 无限循环,等待信号 |
| | while(1) { |
| | pause(); // 使进程暂停直到接收到信号 |
| | } |
| | |
| | return 0; |
| | } |

1. sigemptyset

功能:初始化信号集,将其中的所有信号都设置为未选择状态。

头文件<signal.h>

原型int sigemptyset(sigset_t *set);

参数

  • set:指向信号集的指针,该信号集将被初始化为不包含任何信号的集合。

返回值:成功时返回0;失败时返回-1,并设置errno以指示错误。

2. sigaddset

功能:向信号集中添加一个信号。

头文件<signal.h>

原型int sigaddset(sigset_t *set, int signum);

参数

  • set:指向信号集的指针。
  • signum:要添加到信号集中的信号编号。

返回值:成功时返回0;失败时返回-1,并设置errno以指示错误。

3. sigdelset

功能:从信号集中删除一个信号。

头文件<signal.h>

原型int sigdelset(sigset_t *set, int signum);

参数

  • set:指向信号集的指针。
  • signum:要从信号集中删除的信号编号。

返回值:成功时返回0;失败时返回-1,并设置errno以指示错误。

4. sigaction

功能:查询或更改与特定信号相关联的动作。

头文件<signal.h>

原型int sigaction(int sig, const struct sigaction *act, struct sigaction *oact);

参数

  • sig:指定要更改或查询其行为的信号编号。
  • act:如果非NULL,则指向一个sigaction结构体,该结构体指定了新信号处理器及其相关标志。
  • oact:如果非NULL,则指向一个sigaction结构体,该结构体将包含调用前的信号处理器及其相关标志。

sigaction结构体

  • sa_handler:指向信号处理函数的指针,或使用SIG_IGN忽略信号,或使用SIG_DFL恢复默认行为。
  • sa_sigaction:指向一个接受额外信息的信号处理函数的指针(SA_SIGINFO标志)。
  • sa_mask:一个信号集,指定了在执行信号处理函数期间应被阻塞的信号。
  • sa_flags:指定信号处理选项的位掩码。

返回值:成功时返回0;失败时返回-1,并设置errno以指示错误。

网络(下一篇网络详解,这里只做略)

  • socket
    • 头文件<sys/socket.h>
    • 功能:创建一个新的套接字。
    • 参数
      • domain:协议族(如AF_INET)。
      • type:套接字类型(如SOCK_STREAM)。
      • protocol:特定于协议的选项(通常为0)。
    • 返回值:成功时返回套接字的文件描述符;失败时返回-1,并设置errno。
相关推荐
xiaozhiwise1 分钟前
Linux ASLR
linux
wellnw2 分钟前
[linux] linux c实现共享内存读写操作
linux·c语言
a_安徒生20 分钟前
linux安装TDengine
linux·数据库·tdengine
追风赶月、27 分钟前
【Linux】线程概念与线程控制
linux·运维·服务器
小字节,大梦想29 分钟前
【Linux】重定向,dup
linux
CP-DD41 分钟前
Docker 容器化开发 应用
运维·docker·容器
blessing。。1 小时前
I2C学习
linux·单片机·嵌入式硬件·嵌入式
2202_754421542 小时前
生成MPSOC以及ZYNQ的启动文件BOOT.BIN的小软件
java·linux·开发语言
努力的悟空2 小时前
国土变更调查拓扑错误自动化修复工具的研究
运维·自动化
运维&陈同学2 小时前
【zookeeper03】消息队列与微服务之zookeeper集群部署
linux·微服务·zookeeper·云原生·消息队列·云计算·java-zookeeper