【Unix高级编程】现阶段函数汇总

来源:互联网 发布:mac flash过期 编辑:程序博客网 时间:2024/05/18 15:06
【动态加载】
"dlopen"(3)
#include <dlfcn.h>  //必须包含的头文件
void *dlopen(const char *filename, int flag);
功能:加载filename指定的动态库,返回一个地址。
参数:"filename"指定动态库的名字
 flag: "RTLD_LAZY" 延迟加载
 flag: "RTLD_NOW"  立即加载
返回值:NULL 失败


"dlclose"(3)
int dlclose(void *handle);
功能:使动态库的引用计数减 1,如果引用为0动态库卸载
参数:
"handle" dlopen(3)的返回值
返回值:  0 成功;非 0 失败


"dlsym"(3)
void *dlsym(void *handle, const char *symbol);
功能:在handle指定的库文件中,查找symbol,找到符号将其加载到内存
参数:
"handle" dlopen(3)的返回值
"symbol" 符号
返回值:这个symbol加载到内存里的地址
NULL 在库中找不到symbol指定的函数


"dlerror"(3)
char *dlerror(void);
功能:获取最近一次调用dlopen、dlclose、dlsym函数产生的错误信息
参数:void
返回值:NULL 代表没有错误


【程序中的错误处理】
"perror"(3)
#include <stdio.h>
void perror(const char *s);
功能:将"最近一次函数调用的错误信息"以标准错误输出形式输出
参数:"s" 用户需要的提示信息
返回值:void


"strerror"(3)
#include <string.h>
char *strerror(int errnum);
功能:返回errnum错误号对应的描述信息
参数:"errnum" 错误编号
返回值:错误的描述信息,如果errnum不存在,返回"Unknown error nnn"


【内存映射到进程的地址空间】
"mmap"(2)
#include <sys/mman.h>  //包含单独的头文件
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
功能:将文件或设备映射到进程的地址空间里
参数:
"addr" 指定了映射的起始地址。如果为 NULL 这个地址由内核决定
"length" 指定了映射的长度
"prot" 
   PROT_EXEC  executed.//映射页可执行
   PROT_READ  read.//映射页可读
   PROT_WRITE written.//映射页可写
   PROT_NONE  not be accessed.//映射页不可以被访问
"flags"
MAP_SHARED Share.//可以被其他进程共享,更新的内容可以显示到其他进程和文件中
MAP_PRIVATE private.//不能被其他进程共享,更新的内容不能显示到文件里
MAP_ANONYMOUS //与根文件没有关系。映射的就是物理内存 anonymous
"fd" 文件描述符,暂用不着,是 0
"offset" 偏移量,暂用不着,是 0
返回值:
成功 - 返回一个指向映射区域的地址
失败 - 返回"MAP_FAILED",errno被设置


"munmap"(2)
int munmap(void *addr, size_t length);
功能:解除映射
参数:
"addr" mmap(2)的返回值,就是映射内存的起始虚拟地址
"length" mmap(2)中映射的长度
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


【文件操作】
"open"(2)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int open(const char *pathname, int flags,...); //正确写法,真正原型
功能:打开一个文件,并返回一个文件描述符
参数:
"pathname" 文件路径
"flags" (以下 3 个选项,必须选择其 1)
O_RDONLY //只读方式打开文件
O_WRONLY //只写方式打开文件
O_RDWR   //可读可写方式打开文件
file creation flags //文件创建标记
O_CREAT //如果文件不存在,则创建文件。mode(文件权限)还需要指定
O_EXCL //需要和 O_CREAT 标记一起使用,如果文件不存在,则创建文件;如果文件存在,则函数调用失败
O_TRUNC //如果文件存在,将这个文件内容清0;如果不存在,就创建文件
file status flags //文件状态标记
O_APPEND //追加到文件末尾
"..." 代表"可变参数"
返回值:
成功 - 返回一个新的文件描述符
失败 - 返回-1,errno被设置 


"close"(2)
#include <unistd.h>
int close(int fd);
功能:关闭一个文件描述符
参数:"fd" open(2)函数的返回值。指定一个文件描述符
返回值:
成功 - 返回 0
失败 - 返回-1,errno被设置


"read"(2)
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
功能:从fd指定的文件描述符读取内容
参数:
"fd" open(2)的返回值,指定了要从这个文件描述符里读取
"buf" 存储读取内容空间的首地址
"conunt" 本次读取的最大字节数
返回值:
成功 - 返回读取的字节数(也会比count小),0 代表读取到了文件的末尾
失败 - 返回 -1 ,errno被设置


"write"(2)
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
功能:向fd指定的文件描述符写入内容
参数:
"fd" open(2)的返回值,指定了要写入文件的描述符
"buf" 从buf指定地址的空间里读取数据
"count" 最多向文件中写入的字节数
返回值:
成功 - 返回实际写入文件的字节数(也会比count小),0 代表没有内容被写入了
失败 - 返回 -1,errno被设置


"lseek"(2)
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
功能:重新设置文件读写的位置
参数:
"fd" 指定了文件。open(2)的返回值
"offset" 相对与位置的偏移字节数
"whence" 
SEEK_SET 文件的头部
SEEK_CUR 文件的当前位置
SEEK_END 文件的尾部
返回值:
成功 - 返回相对文件头的字节数
失败 - 返回 -1,errno被设置


【文件重定向/文件描述符】
"dup"(2)
#include <unistd.h>
int dup(int oldfd);
功能:复制一个文件描述符
参数:"oldfd" 源描述符
返回值:
成功 - 返回一个新的文件描述符,未被使用的、最小的数字
失败 - 返回 -1,errno被设置


"dup2"(2)
int dup2(int oldfd, int newfd);
功能:复制一个新的文件描述符
参数:
"oldfd" 旧的文件描述符
"newfd" 新的文件描述符
返回值:
成功 - 返回一个新的文件描述符,未被使用的、最小的数字
失败 - 返回 -1,errno被设置


【获取文件属性】
"stat"(2)
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
功能:获取文件的属性
参数:
"path" 文件路径,要获取属性的文件地址
"buf" 将文件的属性填充到buf指定的空间里
补充:
struct stat /*存放文件属性的结构体*/
struct stat {
   dev_t     st_dev;     /* 用于设备文件描述符 */ignore
   ino_t     st_ino;     /* inode号 */ 1
   mode_t    st_mode;    /* 类型/权限protection */ 1
   nlink_t   st_nlink;   /* 硬链接数 */ 1
   uid_t     st_uid;     /* 属主user ID */ 1
   gid_t     st_gid;     /* 属组组ID */ 1
   dev_t     st_rdev;    /* 设备文件ID */ignore
   off_t     st_size;    /* 总字节长度 */ 1
   blksize_t st_blksize; /* blocksize for file system I/O */ignore
   blkcnt_t  st_blocks;  /* number of 512B blocks allocated*/ignore
   time_t    st_atime;   /* 最后一次访问时间 */ 1
   time_t    st_mtime;   /* 最后修改时间 */ 1
   time_t    st_ctime;   /* 状态改变时间 */ 1
};
返回值:
成功 - 返回 0 
失败 - 返回 -1,errno被设置


"getpwuid"(3)
#include <sys/types.h>
#include <pwd.h>
struct passwd *getpwuid(uid_t uid);
功能:获取uid相关信息
参数:"uid" 指定的uid
返回值:
成功 - 返回一个指向 struct passwd结构体类型的变量地址
失败 - 返回 NULL,没找到或有错误产生,如果是错误,errno被设置
struct passwd {
   char   *pw_name;       /* username */
   char   *pw_passwd;     /* user password */
   uid_t   pw_uid;        /* user ID */
   gid_t   pw_gid;        /* group ID */
   char   *pw_gecos;      /* user information */
   char   *pw_dir;        /* home directory */
   char   *pw_shell;      /* shell program */
};


"getprgid"(3)
#include <sys/types.h>
#include <grp.h>
struct group *getgrgid(gid_t gid);
功能:获取gid相关信息
参数:"gid"指定的gid
返回值:
成功 - 返回一个指向 struct group结构体类型的变量地址
失败 - 返回 NULL,没找到或有错误产生,如果是错误,errno被设置
struct group {
   char   *gr_name;       /* group name */
   char   *gr_passwd;     /* group password */
   gid_t   gr_gid;        /* group ID */
   char  **gr_mem;        /* group members */
};


使用ctime(3)将时间由数字转换为字符串类型时间显示
"ctime"(3)
#include <time.h>
char *ctime(const time_t *timep);
功能:转换为日期和时间
参数:"timep" 指定的st_atime
返回值:
成功 - 返回时间值的描述
失败 - 返回 -1,errno被设置
struct tm {
   int tm_sec;         /* seconds */
   int tm_min;         /* minutes */
   int tm_hour;        /* hours */
   int tm_mday;        /* day of the month */
   int tm_mon;         /* month */
   int tm_year;        /* year */
   int tm_wday;        /* day of the week */
   int tm_yday;        /* day in the year */
   int tm_isdst;       /* daylight saving time */
};


【文件夹操作】
"opendir"(3)
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
功能:打开一个文件夹
参数:"name" 指定了要打开的文件夹的名字
返回值:
成功 - 一个指向文件夹流的首地址的指针
失败 - 返回 NULL,errno被设置


"readdir"(3)
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
功能:读取一个文件夹
参数:"dirp" opendir(3)的返回值,要读取内容的文件夹
返回值:
成功 - 返回一个结构体指针
失败 - 返回 NULL,到达文件末尾或者错误发生,如果是错误产生,errno被设置
struct dirent {
   ino_t          d_ino;       /* inode号 */
   off_t          d_off;       /* 下一个偏移两 */ ignore
   unsigned short d_reclen;    /* 记录长度 */ ignore
   unsigned char  d_type;      /* 不被所有文件支持 */ ignore
   char           d_name[256]; /* 文件名filename */
};


"closedir"(3)
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
功能:关闭一个文件夹
参数:"dirp" opendir(3)的返回值
返回值:
成功 - 返回 0
失败 - 失败 -1,errno被设置


"rewinddir"(3)
#include <sys/types.h>
#include <dirent.h>
void rewinddir(DIR *dirp);
功能:重置文件夹流到文件夹的开始位置
参数:"dirp" opendir(3)的返回值
返回值:无返回值。


"telldir"(3)
#include <dirent.h>
long telldir(DIR *dirp);
功能:当前文件夹流的位置
参数:"dirp" opendir(3)的返回值
返回值:
成功 - 返回当前文件夹流的位置
失败 - 返回 -1,errno被设置


【文件锁】
"fcntl"(2) //使用该系统调用函数完成对文件的加锁
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );
功能:操作文件描述符
参数:
"fd" open(2)的返回值,指定要操作的文件(描述符)
"cmd" 命令。对文件描述符进行操作的命令
F_SETLK 设置锁-非阻塞模式,进程遇锁立即以错误返回,返回错误
F_SETLKW 设置锁-阻塞模式,进程遇锁将等待冲突锁直到锁被释放
F_GETLK 获取锁
"..." 可变参数(需要or不需要"取决与cmd参数")
"..."=="lock"
struct flock {
   short l_type;    /*Type of lock*/ 读锁/写锁/解锁
"F_RDLCK,F_WRLCK,F_UNLCK"
   short l_whence;  /*How to interpret l_start*/位置:开始/当前/末尾
                    "SEEK_SET, SEEK_CUR, SEEK_END"
   off_t l_start;   /*Starting offset for lock*/
   off_t l_len;     /*Number of bytes to lock*/
   pid_t l_pid;     /*PID of process blocking our lock
                       (F_GETLK only) */
};
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


【文件操作其他更多...】
"chdir"(2) //cd 命令就是调用封装的 chdir 系统函数
#include <unistd.h>
int chdir(const char *path);
功能:改变工作路径
参数:"path" 目标工作路径
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


"mkdir"(2) //mkdir 命令就是调用封装的 mkdir 系统函数
#include <sys/stat.h>
#include <sys/types.h>
int mkdir(const char *pathname, mode_t mode);
功能:创建一个文件夹或目录
参数:
"pathname" 要创建的文件夹名字
"mode" 新的文件夹的权限,例如 0664 或 mode & ~umask & 0777
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


"getcwd"(3) //pwd 命令就是调用封装的 getcwd 系统函数
#include <unistd.h>
char *getcwd(char *buf, size_t size);
功能:获取当前的工作路径
参数:
"buf" 将当前路径的绝对路径名字拷贝到buf指定的地址空间里
"size" 拷贝的长度
返回值:
成功 - 当前工作路径的首地址指针
失败 - 返回 NULL,errno被设置


"rmdir"(2) //rm -r 命令就是调用封装的 rmdir 系统函数
#include <unistd.h>
int rmdir(const char *pathname);
功能:删除一个目录
参数:"pathname" 要删除的文件夹名字
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


"link"(2) / "symlink"(2) //其中link可做命令行指令使用
#include <unistd.h>
int link(const char *oldpath, const char *newpath);
功能:为文件创建一个新名字 - 硬链接(非拷贝内容)
参数:
"oldpath" 原文件路径
"newpath" 新文件路径
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


"unlink"(2)
#include <unistd.h>
int unlink(const char *pathname);
功能:删除一个硬链接文件名字
参数:"pathname" 文件名
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


"rename"(2) //mv 命令就是调用封装的 rename 系统函数
#include <stdio.h>
int rename(const char *oldpath, const char *newpath);
功能:更改文件名或文件路径
参数:
"oldpath" 原文件名/路径
"newpath" 新文件名/路径
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


"chmod"(2)
#include <sys/stat.h>
int chmod(const char *path, mode_t mode);
功能:改变文件的权限
参数:
"path" 文件名
"mode" 权限属性宏
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


【创建进程】
"fork"(2)
#include <unistd.h>
pid_t fork(void);
功能:创建一个子进程
参数:void
返回值:
成功 - 在父进程里子进程的"pid被返回",在子进程里返回 0 
失败 - 在父进程里返回 -1,子进程没有被创建,errno被设置


"getpid"(2)/"getppid"(2)
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void); //获取自己的pid
pid_t getppid(void); //获取自己父进程的pid


"vfork"(2)
#include <sys/types.h>
#include <unistd.h>
pid_t vfork(void);
功能:创建一个子进程,并且阻塞父进程
参数:void 不需要参数
返回值:
成功 - 返回 0 是子进程,非 0 是父进程
失败 - 返回 -1,errno被设置


【退出进程】
"exit"(3)
#include <stdlib.h>
void exit(int status);
功能:使进程正常终止/退出
参数:"status" 保存子进程退出状态 "获取status参数的低8位,因此最大64"
习惯上,使用"EXIT_SUCCESS""EXIT_FAILURE"两个宏作为参数,分别表示成功和失败,多数系统中定义为 0 和 1,一般建议使用宏,有"更好的兼容性"。
exit(EXIT_SUCCESS);
exit(EXIT_FAILURE);
返回值:无返回值


"_exit"(2)
#include <unistd.h>
void _exit(int status);
功能:退出进程
参数:"status" 文件描述符
返回值:无返回值


在进程终止之前可以做一些处理工作
"atexit"(3)
#include <stdlib.h>
int atexit(void (*function)(void));
功能:向进程注册,进程终止之前调用的函数
参数:void (*function)(void) 进程结束时要调用的函数,无参数
返回值:
成功 - 返回 0
失败 - 返回非 0


"on_exit"(3)
#include <stdlib.h>
int on_exit(void (*function)(int , void *), void *arg);
功能:向进程注册,进程终止之前调用的函数
参数:
void (*function)(int , void *) 进程结束时要调用的函数,两个参数
function函数里的 int 是 return 的数字传到int里 
"arg" function函数里的第 2 个参数
返回值:
成功 - 返回 0
失败 - 返回非 0


【进程的同步】
"wait"(2)
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status); 
功能:等待子进程的结束,进程退出的信息被记录到status指定的内存空间里
参数:"status" 保存子进程退出状态 "获取status参数的低8位,因此最大64"
WIFEXITED(status) //通过检测status来判断子进程是否正常死亡
WEXITSTATUS(status) //这个宏只能在上个宏返回真的情况下使用,获取子进程的退出状态码,可直接打印(判断上个宏时打印)
WIFSIGNALED(status) //检测进程是否被信号终止(就是进程非正常死亡)
WTERMSIG(status) //返回终止子进程的信号的编号,只有在上个宏返回真的情况下才能使用,可直接打印(判断上个宏时打印)
~给进程发信号,命令行:kill -9 pid //进程被信号杀死后返回状态码9
返回值:
成功 - 退出的子进程的pid
失败 - 返回 -1


"waitpid"(2)
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);
功能:等待pid指定子进程的状态的改变(挂起)
参数:
"pid" 
< -1 等待任意一个子进程,子进程的组id等于pid的绝对值
==-1 等待任意一个子进程
== 0 等待任意一个同组的子进程
>  0 等待子进程的pid等于指定pid的值
"status" 保存子进程退出状态,等同与wait(2)的参数
"options" 
WNOHANG 非阻塞等待
0 指定了0的情况下阻塞等待:waitpid(-1, &status, 0)
返回值:
成功 - 返回子进程的pid(使用 0 指定WNOHANG,没有子进程结束)
失败 - 返回 -1,函数调用错误


【加载新的进程映像】
"execve"(2)  //执行程序
#include <unistd.h>
int execve(const char *filename,char *const argv[], \
  char *const envp[]); //真正的系统调用该函数,其他都是包装
int execl(const char *path,const char *arg,...);
int execlp(const char *file,const char *arg,...);
int execle(const char *path,const char *arg,..., \
  char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], \
            char *const envp[]);
功能:都是加载一个程序进程映像 //使用新的进程映像替换掉当前进程映像
参数:
1)所有函数名带"p"的,第一个参数都是"file",会到PATH环境变量下找;
不带p的第一个参数都是"path",需要将路径写全。
2)函数当中第一个参数是新进程映像的路径。
如execv("/bin/ls", ...); //指定路径
如execvp("ls", ...); //依赖PATH环境变量
3)所有函数名结尾带"e"字符的,说明可以更改环境变量 char *const envp[]
4)函数名中带"l""v"的区别:"list" str1,str2,str3,NULL; "vector"首地址
返回值:
正确执行 - 不返回
执行错误 - 才返回 -1,errno被设置
char *const ps_argv[] = {"ps", "-o", "pid,ppid,pgrp,comm", NULL};
char *const ps_envp[] = {"name=tarena", NULL};
execl("/bin/ps", "ps", "-o", "pid,ppid,pgrp,comm", NULL);
elecl("/bin/ps", "ps", NULL); //相当于在程序中执行了ps命令
execv("/bin/ps", ps_argv);
execlp("ps", "ps", "-o", "pid,ppid,pgrp,comm", NULL);
execvp("ps", ps_argv);
execle("/bin/ps", "ps", "-o", "pid,ppid,pgrp,comm", NULL, ps_envp);
execvpe("ps", ps_argv, ps_envp);


【环境变量】
"getenv"(3)
#include <stdlib.h>
char *getenv(const char *name);
功能:获取一个环境变量
参数:"name" 要找的环境变量的名字
返回值:
成功 - 返回一个环境变量字符串的首地址
失败 - NULL,找不到这个环境变量


"putenv"(3)
#include <stdlib.h>
int putenv(char *string);
功能:改变或添加一个环境变量
参数:"string" 格式:name=value
返回值:
成功 - 返回 0
失败 - 返回非 0


"setenv"(3)
#include <stdlib.h>
int setenv(const char *name, const char *value, int overwrite);
功能:改变或增加一个环境变量
参数:
"name" 要添加或改变的环境变量名
"value" 环境变量的值
"overwrite" 环境变量存在,值取 0 环境变量值不变;值取非 0 环境变量值被改为value
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置




"unsetenv"(3)
int unsetenv(const char *name);
功能:删除环境变量(环境变量不存在,函数执行成功,环境变量不变)
参数:"name" 环境变量名
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


【管道】
"pipe"(2) //无名管道,应用于有亲缘关系的两个进程间的通讯
#include <unistd.h>
int pipe(int pipefd[2]);
功能:创建管道
参数:"pipefd[2]" 含两个整形数元素的数组
pipefd[0] 负责写数据的进程关闭管道的"读端文件描述符"
pipefd[1] 负责读数据的进程关闭管道的"写端文件描述符"
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


父进程: 子进程
1)pipe创建管道 --
2)fork创建子进程 子进程被创建
3)close(pipefd[0]); close(pipefd[1]);
4)向管道写入内容 从管道里读取内容/输出读取到的内容
5)wait(NULL); 退出
6)退出


"mkfifo"(3) //有名管道
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
功能:创建一个FIFO文件,用于进程间的通信
参数:
"pathname" 文件的路径/文件名
"mode" 文件的权限
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


【转换字母大小写格式】
"toupper"(3) / "tolower"(3)
#include <ctype.h>
int toupper(int c);
int tolower(int c);
功能:转换字母大小写格式 upper大写,lower小写
参数:"c" 字符
返回值:
成功 - 返回字符的值(ASCII码)


【信号】用户自定义信号处理函数的注册
"signal"(2)
#include <signal.h>
typedef void (*sighandler_t)(int); //函数指针(回调)
sighandler_t signal(int signum, sighandler_t handler);
功能:设置handler为信号signum的处理函数
参数:
"signum" 信号的编号或者信号名字
"handler" 信号的处理函数
返回值:
成功 - 返回以前的这个信号的处理函数 //以前的没用,可不用返回
失败 - 返回SIG_ERR,函数执行错误


【信号的终止】
"kill"(2)
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
功能:给一个进程发送信号(给进程号为pid的进程发送sig信号)
参数:
"pid" 进程pid号(>0 的情况)
"sig" 信号的编号
返回值:
成功 - 返回 0
失败 - 返回-1,errno被设置


"raise"(3)
#include <signal.h>
int raise(int sig);
功能:发送一个信号给自己的进程
参数:"sig" 指定要发送给自己的信号编号
返回值:
成功 - 返回 0
失败 - 返回非 0


"alarm"(2) "闹钟"
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
功能:整理一个信号在seconds指定的时间到达自己的进程
参数:"seconds" 指定的时间,默认单位:秒
0 没有设置新闹钟
返回值:
成功 - 返回剩余的秒数,在闹钟时间到达的时候产生 14)SIGALRM 信号,发送给自己的进程
失败 - 返回 0 取消闹钟


"sleep"(3) "睡眠"
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
功能:给程序指定seconds时间的睡眠
参数:"seconds" 指定的时间,默认单位:秒
返回值:
成功 - 返回 0
失败 - 返回剩余的秒数,在进程被信号中断的时候,返回剩余秒数


【信号阻塞、未决信号】
"sigprocmask"(2)
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
功能:检测或改变为阻塞的信号
参数:
类型sigset_t /* 集合类型,用于标识信号的阻塞和未决状态 */
"how" 
SIG_BLOCK 将进程当前的信号组合集合和set指定的集合/*合并*/
SIG_UNBLOCK 将set集合里指定的信号从进程当前阻塞的信号集里/*移除*/解除set信号集里指定的信号的阻塞
SIG_SETMASK 将进程阻塞的信号集/*设置为参数set的集合*/
"set" 要操作的/*新的信号集*/
"oldset" 如果oldset非空,将进程的原先的阻塞信号集/*存储*/到oldset指定的集合里;如果oldset是 NULL,则不会存储原来的信号阻塞集
返回值:
成功 - 返回 0
失败 - 返回 -1


"sigemptyset" //初始化,清空信号集
#include <signal.h>
int sigemptyset(sigset_t *set);
功能:将集合里的成员全部清空
参数:"set" 指定的信号集合
返回值:
成功 - 返回 0
失败 - 返回 -1


"sigfillset" //填充信号集
#include <signal.h>
int sigfillset(sigset_t *set);
功能:将集合的所有成员全部填充
参数:"set" 指定的信号集合
返回值:
成功 - 返回 0
失败 - 返回 -1


"sigaddset" //添加信号到信号集
#include <signal.h>
int sigaddset(sigset_t *set, int signum);
功能:将signum信号添加到set指定的集合里
参数:
"set" 指定的信号集合
"signum" 指定的信号编号
返回值:
成功 - 返回 0
失败 - 返回 -1


"sigdelset" //删除信号集里指定的信号
#include <signal.h>
int sigdelset(sigset_t *set, int signum);
功能:从set指定的集合里将signum指定的信号编号删除
参数:
"set" 指定的信号集合
"signum" 指定的信号编号
返回值:
成功 - 返回 0
失败 - 返回 -1


"sigismember" //测试信号是否是信号集里的成员
#include <signal.h>
int sigismember(const sigset_t *set, int signum);
功能:测试signum是否是set集合里的一个成员
参数:
"set" 指定的信号集合
"signum" 指定的信号编号
返回值:
成功 - 返回 1 代表signum是set集合的成员,0 代表不是。
失败 - 返回 -1


"检测信号是否处于未决状态",需要使用sigpending函数:
"sigpending"(2)
#include <signal.h>
int sigpending(sigset_t *set);
功能:检测未决信号
参数:"set" 未决信号集被返回到set指定的集合里
返回值:
成功 - 返回 0
失败 - 返回 -1


【pause函数】
"pause"(2) //暂停/中止
#include <unistd.h>
int pause(void);
功能:等待信号
参数:void
返回值:
成功 - 不返回,阻塞信号,信号捕获后再返回
失败 - 返回-1,errno被设置


【setitimer函数】
"setitimer"(2)
#include <sys/time.h>
//int getitimer(int which, struct itimerval *curr_value);
int setitimer(int which, const struct itimerval *new_value,
             struct itimerval *old_value);
功能:设置一个间歇时间(计时器/定时器)
参数:
"which" 3选1
ITIMER_REAL -> SIGALRM 信号(倒计时,按时间减少真实时间)
ITIMER_VIRTUAL -> SIGVTALRM 信号(仅当遇到该信号时开始倒计时)
ITIMER_PROF -> SIGPROF 信号
"new_value" 结构体变量地址
"old_value" 结构体变量地址
struct itimerval {
   struct timeval it_interval; /*next value重复间隔时间*/
   struct timeval it_value;    /*current value初始间隔时间(倒计时)*/
};
struct timeval {
   long tv_sec;        /*seconds秒*/  /** 秒-毫秒-微妙:各1000倍 **/
   long tv_usec;       /*microseconds微秒*/
};
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


【进程间通讯】
"ftok"(3)
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
功能:将pathname和proj_id转换为system v IPC键值
参数:
"pathname" 有效的文件名
"proj_id" 取一个数字的低8位(0~255) //取21和取277(277-256)结果都是21
//多次调用ftok的时候,参数pathname和proj_id的组合一样,那么得到的键值也是一样的,必须保证键值唯一。
返回值:
成功 - 返回一个键值
失败 - 返回 -1,errno被设置


【消息队列】
"msgget"(2)
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
功能:获取一个消息队列的id
参数:
"key" 跟消息队列向关联的键值,ftok(3)的返回值
"msgflg" 
IPC_CREAT 如果消息队列不存在,则创建并返回创建的消息队列id
如果存在,则返回该消息队列id
IPC_EXCL 如果消息队列不存在,则创建并返回创建的消息队列id
如果消息队列存在,masgget失败,errno被设置为EEXIST
可以指定消息队列的操作权限。做"或 |"操作,权限参见open(2)的mode。
返回值:
成功 - 返回消息队列的id
失败 - 返回 -1,errno被设置


"msgsnd"(2) /** 写入消息 **/
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
功能:往消息队列里添加数据
参数:
"msqid" msgget(2)的返回值,就是队列的id
"msgp" 消息的结构体
"msgsz" 消息的长度,不包含消息的类型mtype,只有mtext的长度
"msgflg" 
IPC_NOWAIT 非阻塞,消息队列没有空间的时候,立即返回
0 阻塞,消息队列没有空间的时候,阻塞等待
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置
struct msgbuf {
   long mtype;       /*message type, must be > 0 */
   char mtext[1];    /*message data该数组可变长,该字节往后都是数据*/
}; "使用此结构体之前要先声明该结构体(数组变长),并定义结构体变量"


"msgrcv"(2)  /** 移除消息 **/
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, \
               int msgflg);
功能:从msqid消息队列中移除一条消息
参数:
"msqid" msgget(2)的返回值,消息队列的id
"msgp" 指定一块内存空间,将消息存放到这块空间里
"msgsz" metxt的最大尺寸
"msgtyp" 消息的类型(需要与添加消息的时候指定的数字一致)
"msgflg" 
IPC_NOWAIT 消息队列中没有消息,立即返回
0 消息队列中没有消息,等待
返回值:
成功 - 返回从消息队列中获取的消息的字节数
失败 - 返回 -1,errno被设置 


【共享内存】
"shmget"(2)
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
功能:分配一块共享内存区域
参数:
"key" 根据key的值获取共享内存的id,ftok(3)的返回值
"size" 需要的共享内存的大小/尺寸
"shmflg" 
IPC_CREAT 如果存在共享内存,则返回;不存在就创建
返回值:
成功 - 返回共享内存的id
失败 - 返回 -1


"shmat"(2) /** 映射 **/
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:将共享内存映射到虚拟地址空间里
参数:
"shmid" 共享内存的id,shmget(2)的返回值
"shmaddr" NULL 代表系统自动分配虚拟空间
"shmflg" 
SHM_RDONLY 只读(共享内存权限为只读)
0 可读可写
返回值:
成功 - 返回跟共享内存相关的虚拟地址(用户空间)
失败 - 返回(void *)-1,errno被设置


"shmdt"(2) /** 解除映射 **/
#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);
功能:解除shmat的映射
参数:"shmaddr" shmat(2)的返回值
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


【TCP-服务器编程模型】
/** 1.<1> 创建socket通讯端 **/
"socket"(2)
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
功能:创建一个通讯端点(返回一个文件描述符)
参数:
"domain"
AF_INET 用于ipv4的通讯
AF_INET6 用于ipv6的通讯
"type"
SOCK_STREAM 传输层选用的是TCP协议,面向数据流
SOCK_DGRAM 传输层选用的是UDP协议,面向数据包
"protocol" 0
返回值:
成功 - 返回新的文件描述符
失败 - 返回 -1,errno被设置




/** 1.<2> 将通讯端和服务器的ip地址和端口号绑定 **/
"bind"(2)
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
功能:将一个名字绑定到一个socket(第一个参数绑定到第二个参数)
参数:
"sockfd" socket(2)的返回值
"addr" socket pair通讯对,通用协议族 //ip地址和端口号构成的一个结构体
"addrlen" addr的长度
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置




补充:"man in.h"头文件下包含以下3个结构体:
"<netinet/in.h>"
#include <netinet/in.h>
struct sockaddr 通用协议族结构体
struct sockaddr_in ipv4协议族的结构体
struct sockaddr_in6 ipv6协议族的结构体
struct sockaddr {
   sa_family_t sa_family;
   char        sa_data[14];
};
struct sockaddr_in {
sa_family_t sin_family; /* 取值:AF_INET */
in_port_t sin_port; /* Port number:5000以下留给系统*/
struct in_addrsin_addr;/* IP address */
};
struct in_addr {
in_addr_t s_addr;/** INADDR_ANY 表示任意IP均可与服务器通信 **/
}




需要将ip地址的"点分十进制(ddd.ddd.ddd.ddd)"的字符串和无符号整形两种类型互相转换。
/** 点分十进制字符串 -> 网络字节序(无符号整数) **/ 转换
"inet_pton"(3)
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
功能:将ipv4或ipv6的字符串形势的ip地址转换为struct in_addr二元形式
参数:
"af" 
AF_INET IPv4网络
AF_INET6 IPv6网络
"src" 点分十进制的字符串格式
"dst" struct in_addr类型的内容
返回值:
成功 - 返回 1
失败 - 返回 0,代表src是无效地址
失败 - 返回 -1,errno被设置




/** 网络字节序(无符号整数) -> 点分十进制字符串 **/
"inet_ntop"(3)
#include <arpa/inet.h>
const char *inet_ntop(int af,const void *src,char *dst,socklen_t size);
功能:将ipv4或ipv6的地址从binary(二进制)到text(字符串)
参数:
"af" 
AF_INET IPv4网络
AF_INET6 IPv6网络
"src" struct in_addr类型的内容
"dst" 指定的字符串空间
"size" 拷贝到字符串的大小
返回值:
成功 - 返回字符串的首地址
失败 - 返回 NULL,errno被设置


"inet_ntoa"(3) //扩充
"inet_aton"(3) //扩充




一般情况下计算机配置的是小端,但是网络中使用的是大端。不管计算机使用的是大端还是小端,到"网络中必须使用大端"。
"htonl"(3)系列函数 /** 大小端的字节顺序byte order互相转换 **/
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
"h" 开头的:host主机字节序
"n" 开头的:net网络字节序
"l" 结尾的:long (长整型 32 位) - 可用于IP
"s" 结尾的:short (短整型 16 位) - 可用于端口




/** 1.<3> 监听通讯端 **/
"listen"(2)
#include <sys/types.h>
#include <sys/socket.h>
int listen(int sockfd, int backlog);
功能:监听socket连接
参数:
"sockfd" socket(2)返回值(type参数需指定SOCK_STREAM | SOCK_SEQPACKET)
"backlog" 允许的最大的未决连接数
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


/** 1.<4> 等待客户端连接的到来,返回一个连接描述符 **/
"accept"(2)
#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:创建一个新的连接socket(监听到连接)
参数:
"sockfd" socket(2)的返回值
"addr" 获取客户端的socket pairs(通讯对:ip地址和端口号)
  如果addr为 NULL,addrlen需要置为 NULL
"addrlen" addr结构体变量的长度
返回值:
成功 - 返回 一个新的非负整数文件描述符
失败 - 返回 -1,errno被设置


//<5> 读取客户端发送过来的信息
int r = read(conn_fd, buf, 127);
//<6> 加工处理信息
for(int i = 0; i < r; i++) {
    buf[i] = toupper(buf[i]);
}
//给客户端响应
write(conn_fd, buf, r);
//<7> 和这个客户端业务结束,关闭连接
close(conn_fd);


【TCP-客户端编程模型】
"connect"(2)
#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, \
socklen_t addrlen);
功能:将sockfd连接到addr指定的地址空间
参数:
"sockfd" socket(2)的返回值
"addr" 要连接到的目的地址(struct sockaddr通讯对类型的)
"addrlen" addr的长度
返回值:
成功 - 返回 0 (连接或绑定成功)
失败 - 返回 -1,errno被设置


"select"(2) /** 待扩充,nigix使用的就是此多进程方式 **/


【UDP-服务器编程模型】
/** 1.<3> recvfrom等待客户端数据的到来 **/
"recvfrom"(2) "其他的相关函数自行扩充"
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                struct sockaddr *src_addr, socklen_t *addrlen);
功能:从socket接收消息
参数:
"sockfd" socket(2)的返回值
"buf" 接收消息的内存空间地址
"len" 接收消息的长度
"flags" 0
"src_addr" 源的socket pairs;如果为 NULL,addrlen也就为 NULL
"addrlen" src_addr的长度
返回值:
成功 - 返回接收到的字节数
失败 - 返回 -1,errno被设置


/** 1.<5> sendto响应客户端 **/
"sendto"(2)
#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
              const struct sockaddr *dest_addr, socklen_t addrlen);
功能:通过socket发送消息
参数:
"sockfd" socket(2)的返回值
"buf" 将buf指定的内存空间里的数据发送出去
"len" buf的长度
"flags" 0
"dest_addr" 目标地址
"addrlen" 目标地址的长度
返回值:
成功 - 返回成功发送的字节数
失败 - 返回 -1,errno被设置


【创建线程】
"pthread_create"(3)
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                  void *(*start_routine) (void *), void *arg);
Compile and link with "-pthread". /** 编译加上该库 -lpthread **/
功能:创建一个新的线程
参数:
"thread" 将 tid 存放在该参数的变量空间里
"attr" 取 NULL 采用默认的属性
"start_routine" (函数访问方式,返回值void *,参数void *)
新线程执行的函数
"arg" 是start_routine函数的唯一的参数
返回值:
成功 - 返回 0
失败 - 返回一个错误号,thread未定义。


查看线程自己的tid:
"pthread_self"(3)
#include <pthread.h>
pthread_t pthread_self(void);
功能:获取线程自己的id,即tid (unsigned long int) "%lu"
参数:void
返回值:
总是成功 - 返回线程的id


【退出线程】
"pthread_exit"(3)
#include <pthread.h>
void pthread_exit(void *retval);
功能:终止线程
参数:"retval" 这个值被调用的pthread_join的线程使用
返回值:void
注意:pthread_exit的"参数不能使用局部变量的地址",局部变量栈里。


"pthread_cancel"(3)
#include <pthread.h>
int pthread_cancel(pthread_t thread);
功能:给一个线程发送终止请求
参数:"thread" 指定接收终止请求的线程
返回值:
成功 - 返回 0
失败 - 返回非 0 错误号


【线程分离和汇总】
线程的"分离":
"pthread_detach"(3)
#include <pthread.h>
int pthread_detach(pthread_t thread);
功能:分离一个线程。一个线程终止,资源自动回收,不需要其他线程参与
参数:"thread" 要分离的线程tid
返回值:
成功 - 返回 0
失败 - 返回非 0 错误号


线程的"汇总":
"pthread_join"(3)
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
功能:等待线程终止,回收线程资源
参数:
"thread" 指定要等待的线程的tid
"retval" 存放thread指定的线程的退出状态码
返回值:
成功 - 返回 0
失败 - 返回非 0 错误号


【线程同步 - mutex锁】
"pthread_mutex_init"(3)
"pthread_mutex_lock"(3)
"pthread_mutex_trylock"(3)
"pthread_mutex_unlock"(3)
#include <pthread.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //初始化锁
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
功能:初始化mutex锁
参数:
"mutex" 要初始化的mutex锁
"mutexattr" NULL 缺省
返回值:
成功 - 总是返回 0


int pthread_mutex_lock(pthread_mutex_t *mutex);
功能:加锁,如果这把锁没有锁上,加锁并改成自己拥有且立即返回;
 如果这把锁由其它线程加锁,那么当前线程就挂起等待,直到该锁被解开,当前线程获取这把锁。
参数:"mutex" 指定要上锁的锁。
返回值:
成功 - 返回 0
失败 - 返回错误码


int pthread_mutex_trylock(pthread_mutex_t *mutex);
功能:尝试加锁,如果锁没有被另外的线程使用,立即加锁并返回;
 如果被其他线程加锁,立即返回,并将错误码置为 EBUSY 。
参数:"mutex" 尝试加锁的锁
返回值:
成功 - 返回 0
失败 - 返回错误码


int pthread_mutex_unlock(pthread_mutex_t *mutex);
功能:解开锁,锁原来是锁着的,还是当前线程所拥有的锁。
参数:"mutex" 要解开的锁
返回值:
成功 - 返回 0
失败 - 返回错误码


int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能:销毁锁,并释放mutex持有的资源
参数:"mutex" 要销毁的锁
返回值:
成功 - 返回 0
失败 - 返回错误码


【线程同步 - 条件变量】
"pthread_cond_init"(3)
#include <pthread.h>
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; //初始化条件变量
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
功能:初始化一个条件变量
参数:
"cond" 要初始化的条件变量
"cond_attr" NULL,默认属性
返回值:
成功 - 返回 0
失败 - 返回错误码


int pthread_cond_signal(pthread_cond_t *cond);
功能:通知在cond条件上等待的线程,从中任选一个开始执行
参数:"cond" 指定了条件
返回值:
成功 - 返回 0
失败 - 返回错误码


int pthread_cond_broadcast(pthread_cond_t *cond);
功能:唤醒了所有在cond条件上等待的线程
参数:"cond" 等待的条件
返回值:
成功 - 返回 0
失败 - 返回错误码


int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
功能:1. 解开mutex锁;2. 阻塞等待;3. 当条件成立的时候被唤醒,重新加锁
参数:
"cond" 阻塞等待的条件
"mutex" 被解开的锁
返回值:
成功 - 返回 0
失败 - 返回错误码


int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
功能:类似于pthread_cond_wait,但是有等待周期
参数:
"cond" 阻塞等待的条件
"mutex" 被解开的锁
"abstime" 指定了等待周期的时间
返回值:
成功 - 返回 0
失败 - 返回错误码


int pthread_cond_destroy(pthread_cond_t *cond);
功能:销毁一个变量,释放资源
参数:"cond" 要销毁的条件变量
返回值:
成功 - 返回 0
失败 - 返回错误码


【线程同步 - 信号量】
"sem_init"(3)
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:初始化一个信号量
参数:
"sem" 在sem指定的空间里初始化一个信号量
"pshared" 0 用于多线程之间共享;非 0 用于多进程之间共享
"value" 信号量的初始值
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


"sem_destroy"(3)
#include <semaphore.h>
int sem_destroy(sem_t *sem);
功能:销毁一个信号量
参数:"sem" 要销毁的信号量
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


"sem_post"(3)
#include <semaphore.h>
int sem_post(sem_t *sem);
功能:使信号量的值加 1
参数:"sem" 要操作的信号量
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


"sem_wait"(3)
#include <semaphore.h>
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
功能:使信号量的值减少 1
 如果在减1之前信号量的值>0,立即返回;如果值==0,阻塞等待。
参数:"sem" 要操作的信号量
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置


【进程间通讯 - 信号量集】
"semget"(2)
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
功能:获取一个信号量集的id
参数:
"key" ftok(3)的返回值
"nsems" 信号量集中包含的信号量的个数
"semflg" 
IPC_CREAT 这个信号量集不存在就创建|考虑权限;存在就获取
IPC_EXCL 如果信号量集不存在就创建|考虑权限;存在就报错
mode 等同于文件的mode
返回值:
成功 - 返回信号量集的id
失败 - 返回 -1,errno被设置


"semop"(2)
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(int semid, struct sembuf *sops, unsigned nsops);
功能:对信号量的操作
参数:
"semid" 信号量集的id,semget(2)的返回值
"sops" 信号量的具体操作
"nsops" 操作信号量集中信号量的个数
返回值:
成功 - 返回 0
失败 - 返回 -1,errno被设置
Each semaphore in a semaphore set has the following associated values:
unsigned short  semval;   /* semaphore value */
unsigned short  semzcnt;  /* # waiting for zero */
unsigned short  semncnt;  /* # waiting for increase */
pid_t           sempid;   /* process that did last op */


struct sembuf {
unsigned short sem_num;  /* semaphore number */
short          sem_op;   /* semaphore operation */
short          sem_flg;  /* operation flags */
}
"sem_num" 这个信号量在信号量集里的索引/下标
"sem_op" p/v操作
> 0 (正整数)将这个正整数加上
==0 
< 0 将sem_op加到semval上,semval是信号量的值
如果semval-semop >= 0,semop立即执行
如果semval-semop <  0,IPC_NOWAIT被设置,semop执行失败,errno被设置为EAGAIN
"sem_flg"
IPC_NOWAIT 非阻塞
SEM_UNDO 撤销


对信号量设置初值的操作,对信号量集的操作:
"semctl"(2)
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);
功能:对信号量的控制操作
参数:
"semid" 要操作的信号量集的id,semget(2)的返回值
"semnum" 信号量在信号量集里的索引/下标
"cmd" 指定了操作的命令
GETVAL
SETVAL
...(略)
"..." 
返回值:
成功 - cmd使用GETVAL时,返回semval;cmd使用SETVAL时,返回 0
失败 - 返回 -1,errno被设置
union semun {
int              val;    /* Value for SETVAL */
struct semid_ds *buf;    /* -- */
unsigned short  *array;  /* -- */
struct seminfo  *__buf;  /* -- */
};


【system函数】
"system"(3)
#include <stdlib.h>
int system(const char *command);
功能:执行一个shell命令
参数:"command" 要执行的命令
返回值:
成功 - 返回command命令的退出状态码
失败 - 返回 -1

0 0
原创粉丝点击