总共分为12部分分别是:进程、线程、消息队列、信号量集、共享内存、PGSQL编程、MYSQL编程、网络编程、文件访问、标准I/O、系统数据文件和信息、信号
(一) 进程
1. 进程ID为0的进程通常是调度进程,常常被称为交换进程
进程ID为1的进程通常是init进程,在自举过程结束时由内核调用
进程ID为2的进程页守护进程,负责支持虚拟存储系统的分页操作
2. pid_t getpid( void ); 返回值:调用进程的进程ID #include <unistd.h>
3. pid_t getppid( void ); 返回值:调用进程的父进程ID
4. uid_t getuid( void ); 返回值:调用进程的实际用户ID
5. uid_t geteuid( void ); 返回值:调用进程的有效用户ID
6. gid_t getgid( void ); 返回值:调用进程的实际组ID
7. gid_t getegid( void ); 返回值:调用进程的有效组ID
8. pid_t fork( void );创建子进程,返回值:子进程返回0,父进程返回子进程ID,出错-1
9. #include<sys/wait.h> pid_t wait(int *statloc);//statloc 保存进程终止状态的指针
10. #include<sys/wait.h>pid_t waitpid(pid_t pid,int *statloc,int options);
pid ==-1 等待任一子进程
pid >0 等待其子进程ID与pid相等的子进程
pid == 0 等待其组ID等于调用进程组ID的任一子进程
pid <-1 等待其组ID等于pid绝对值的任一子进程
options:
WCONTINUED 若实现支持作业控制,那么由pid指定的任一子进程在暂停后已经继续,但其状态尚未报告,则返回其状态
WNOHANG 若由pid指定的子进程并不是立即可用的,则waitpid阻塞,此时其返回0
WUNTRACED 若实现支持作业控制,而由pid指定的任一子进程已处于暂停状态,并且其状态自暂停以来还未报告过,则返回其状态
11.#include<unistd.h> int setuid(uid_t uid); 设置实际实际用户ID和有效用户ID;
int setgid(gid_t gid); 设置实际组ID和有效组ID;成功返回0,错误-1
12.#include<stdlib.h>int system(const char *cmdstring)
system返回值如下
-1出现错误
0调用成功但是没有出现子进程
>0 成功退出的子进程的id
(二)线程
1. #include<thread.h> int pthread_equal(pthread_t tid1, pthread_t tid2);
//相等返回非0,否则返回0
2. pthread_t pthread_self(void);返回调用线程的ID
3. int pthread_create(pthread_t *restrict tidp,
const pthread_attr_t *restrict attr, void *(*start_rtn)(void), void *restrict arg) ;
创建线程:成功返回0,否则返回错误编号
4. void pthread_exit(void *rval_ptr);//终止线程
5. int pthread_join(pthread_t thread, void **rval_ptr);
//自动线程置于分离状态,以恢复资源。成功返回0,否则返回错误编号
6. int pthread_cancel(pthread_t tid);
//请求取消同一进程中的其他线程;成功返回0,否则返回错误编号
7. void pthread_cleanup_push(void (*rtn)(void *), void *arg);
//建立线程清理处理程序
8. void pthread_cleanup_pop(int execute);//调用建立的清理处理程序
9. int pthread_detach(pthread_t tid);//使线程进入分离状态,已分离也不出错
10.int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_nutexattr_t *restrict attr)//初始化互斥量;成功0,失败返回错误编号
11.int pthread_mutex_destroy(pthread_mutex_t *mutex);
//若有调用malloc动态分配内存则用该函数释放;成功0,失败返回错误编号
12.int pthread_mutex_lock(pthread_mutex_t *mutex);//锁住互斥量
int pthread_mutex_trylock(pthread_mutex_t *mutex);//尝试上锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);//解锁
成功返回0,否则返回错误编号
13.int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr)//初始化读写锁
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);//释放资源,在释放内存之前使用
成功返回0,否则返回错误编号
14.int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);//在读模式下锁定读写锁
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);//在写模式下锁定读写锁
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);//锁住读写锁
15.int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);//尝试在读模式下锁定读写锁
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);//尝试在写模式下锁定读写锁
成功返回0,否则返回错误编号
16.int pthread_cond_init(pthread_cond_t *restrict cond, pthread_condattr_t * restrict attr)
//初始化条件变量
int pthread_cond_destroy(pthread_cond_t *cond);//去除初始化条件变量
成功返回0,否则返回错误编号
17.int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex)
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex,
const struct timespec *restrict timeout);
//等待条件变为真,如果在给定的时间内条件不能满足,那么会生成一个代表出错码的返回变量 ;成功返回0,错误返回错误编号
18.int pthread_cond_signal(pthread_cond_t *cond);//唤醒等待该条件的某个线程
int pthread_cond_broadcast(pthread_cond_t *cond)//唤醒等待该条件的所有线程
19.int pthread_attr_init(pthread_attr_t *attr);//初始化线程属性
int pthread_attr_destroy(pthread_attr_t *attr);//释放内存空间(动态分配时调用)
成功返回0,否则返回错误编号
20.int pthread_attr_getdetachstate(const pthread_attr_t *restrict attr, int *detachstate);
//获取线程的分离状态
int pthread_attr_setdetachstate(const pthread_attr_t *restrict attr, int detachstate);
//设置分离状态 PTHREAD_CREATE_DETACHED:以分离状态启动线程
PTHREAD_CREATE_JOINABLE:正常启动线程,应用程序可以获取线程的终止状态
成功返回0,否则返回错误编号
21.int pthread_attr_getstack(const pthread_attr_t *restrict attr,void **restrict stackaddr, size_t *restrict stacksize);//获取线程的栈位置
int pthread_attr_setstack(const pthread_attr_t *attr, void *stackaddr, size_t *stacksize)
//设置新建线程的栈位置 ;成功返回0,否则返回错误编号
(三)消息队列
1.每个队列都有一个msqid_ds结构与之相关联:
struct msqid_ds{
struct ipc_perm msg_perm;
msgqnum_t msg_qnum; //消息的数量
msglen_t msg_qbytes; //最大消息的长度
pid_t msg_lspid; //最后一个发送到消息队列的进程ID
pid_t msg_lrpid; //最后一个读取消息的进程ID
time_t msg_stime; //最后一次发送到消息队列的时间
time_t msg_rtime; //最后一次读取消息的时间
time_t msg_ctime; //最后一次改变的时间
。
。
。
};
struct ipc_perm{
uid_t uid;//拥有者有效的用户ID
gid_t gid;//拥有者有效的组ID
uid_t cuid;//创建者有效的用户ID
uid_t cgid;//创建者有效的组ID
mode_t mode; //权限
。
。
}
2.#include <sys/msg.h> int msgget(key_t key, int flag);
//打开一个现存的队列或创建一个新队列;成功返回0,出错返回-1
3.int msgctl(int msqid, int cmd, struct msqid_ds *buf);//对消息队列执行多种操作
cmd 可选:
IPC_STAT 取此消息队列的msqid_ds结构,并将它放在buf指向的结构
IPC_SET:按由buf指向结构中的值,设置与此队列相关结构中的下列四个字段:msg_perm.uid,msg_perm.gid,msg_perm.mode和msg_qbytes.此命令只有下列两种进程才能执行(1)其有效用户ID等于msg_perm.cuid或msg_perm.uid;(2)具有超级用户特权的进程
IPC_RMID:从系统中删除消息队列以及仍在该队列中的所有数据。
成功返回0,失败返回-1
4.int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag)//发送消息到消息队列中
成功返回0, 不成功返回-1并设置errno,错误码:
EACCES 对调用程序来说,调用被否定
EAGAIN 操作会阻塞进程,但(msgflg & IPC_NOWAIT) != 0
EIDRM msqid已经从系统中删除了
EINTR 函数被信号中断
EINVAL 参数msqid无效,消息类型<1,或者msgsz越界了
flag可以指定为IPC_NOWAIT 则不会阻塞直接返回EAGAIN
注:参数msgp指向用户定义的缓冲区,他是如下的结构
struct mymsg
{
long mtypes; 消息类型
char *mtext; 消息文本
}mymsg_t
5.ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);//读取消息
成功则返回消息的数据部分的长度,出错则返回-1
type: type==0返回队列中的第一个消息
type>0 返回队列中消息类型为type的第一个消息
type<0返回队列中消息类型值小于或等于type绝对值的消息(多个取类型值最小的)
(四) 信号量
1. 内核为每个信号量集合设置了一个semid_ds结构:
struct demid_ds{
struct ipc_perm sem_perm;
unsigned short sem_nsems; //信号量的个数
time_t sem_otime; //上一次semop的时间
time_t sem_ctime;//上一次change的时间
。
。
};
2#include<sys/sem.h>. int semget(key_t key, int nsems, int flag);//创建信号量
成功返回一个对应于信号量集标识符的非负整数,不成功返回-1并设置errno,错误码:
EACCES 存在key的信号量,但没有授予权限
EEXIST 存在key的信号量,但是
( (semflg & IPC_CREATE) && (semflg & IPC_EXCL) ) != 0
EINVAL nsems <= 0或者大于系统的限制,或者nsems与信号量集的大小不符
ENOENT 不存在key的信号量,而且(semflg & IPC_CTEATE) == 0
ENOSPC 要超出系统范围内对信号量的限制了
功能:
函数返回与参数key相关的信号量集标识符。
如果键值为IPC_PRIVATE,或者semflg&IPC_CREAT非零且没有信号量集或标识符关联于key,那么函数就创建标识符及与之相关的信号量集。
参数nsems指定了集合中信号量元素的个数,可用0到nsems-1的整数来引用信号量集合中的单个信号量元素。
参数semflg指定信号量集的优先级,权限的设置与文件权限设置相同,并可以通过semclt来修改权限值,在使用信号量元素之前,应该用semctl对其进行初始化。
注意:
函数如果试图创建一个已经存在的信号量集,如果semflg值中包含了IPC_CREAT和IPC_EXCL,则失败并设置errno为EEXIST;否则返回一个已经存在的信号量集的句柄。
3.int semctl(int semid, int semnum, int cmd, …);//信号量控制
如果成功返回一个非负的值,具体返回值取决于cmd的值。
cmd值GETVAL、GETPID、GETNCNT和GETZCNT使semctl返回与cmd相关的值。
如果成功,所有其它的cmd返回0。
如果不成功semctl返回-1并设置errno,必须检测的错误码:
EACCES 对调用程序来说,操作被否定
EINVAL semid的值或cmd的值无效,或者semnum的值为负或者太大
EPERM cmd的值为IPC_RMID或IPC_SET,且调用程序没有所要求的特权
ERANGE cmd为SETVAL或SETALL,而且要设置的值越界了
功能:
函数semctl为信号量集semid的semnum个元素提供了控制操作。参数cmd指定了操作类型,第四个参数arg可选,是否使用取决于cmd的值。
cmd的值:
GETALL 在arg.array中返回信号量集的值
GETVAL 返回一个特定信号量元素的值
GETPID 返回最后一个操纵元素的进程的进程ID
GETNCNT 返回等待元素增加的进程的个数
GETZCNT 返回等待元素变成零的进程的个数
IPC_RMID 删除semid标识的信号量集
IPC_SET 设置来之arg.buf的信号量集的权限
IPC_STAT 将信号量集semid的semid_ds结构成员拷贝到arg.buf中
SETALL 用arg.array来设置信号量集的值
SETVAL 将一个特定的信号量元素的值设定为arg.val
其中有几个命令需要一个arg参数来读取或存储结构
参数arg的类型为union semun,必须要定义这个类型的数据:
union semum
{
int val
struct semid_ds *buf;
unsigned short *array;
}arg;
4. int semop(int semid, struct sembuf *sops, size_t nsops);//信号量的操作
成功返回0,不成功返回-1并设置errno,必须检测的错误码:
E2BIG nsops的值太大
EACCES 对调用程序来说,操作被否定
EAGAIN 操作会阻塞进程但是(sem_flg&IPC_NOWAIT)!= 0
EFBIG 某一个sops条目的sem_num值小于0,或大于信号量集中元素的数目
EIDRM 信号量集标识符semid已经从系统中删除了
EINTR semop被信号中断
EINVAL semid的值无效,或者请求做SEM_UNDO操作的独立信号量集的数量
超出了限制
ENOSPC 已经超出了对请求SEM_UNDO的进程数的限制
ERANGE 操作会造成semval或semadj值得溢出
功能:
semop函数在单个信号量集上原子的执行sops数组中指定的所有操作。如果其中任何一个单独的元素操作会使进程阻塞,进程就会阻塞而不会执行任何操作。
说明:
结构struct sembuf指定了一个信号量元素操作,包含下列成员。
short sem_num 信号量元素的数量(信号量元素在信号量集中的序号)
short sem_op 要执行的特定元素操作
short sem_flg 为操作指定选项的标志符
sem_op如果是大于零的整数,semop就将这个值与sem_num号信号量元素相加,并唤醒所有等待该元素增加的进程。
如果为零,且信号量元素值不为0,semop就会阻塞调用进程(进程在等待0),并增加等待那个信号量元素值变为零的进程计数。
如果sem_op为负数,那么,如果结果不能为负的话,semop就将sem_op值添加到相应的信号量元素值上去。如果操作可能会使元素值为负,semop就将进程阻塞在使信号量元素值增加的事件上。如果结果值为0,那么semop就唤醒等待0的进程。
(五)共享内存
1.内核为每个共享内存设置了一个 shmid_ds结构,它的成员如下:
Struct shmid_ds{
struct ipc_perm shm_perm; //操作权限结构
size_t shm_segsz; //用字节表示的段的长度
pid_t shm_lpid; //最后一个操作的进程ID
pid_t shm_cpid; //创建者的进程ID
shmatt_t shm_nattch //当前连接的进程数量
time_t shm_atime; //最后一次调用shmat的时间
time_t shm_dtime; //最后一次调用shmdt的时间
time_t shm_ctime; //最后一次调用shmtl的时间
。
。
}
2.include<sys/shm.h> int shmget(key_t key, size_t size, int flag);//创建共享内存
size指的是共享内存段的格式n*sizeof(int)则共享内存段将用来存储int类型数据n个
成功返回一个对应于共享内存段标识符的非负整数,不成功返回-1并设置errno,错误码:
EACCES key的共享标识符存在,但没有授予相关的权限
EEXIST key的共享标识符存在,但((shmflg&IPC_CREAT) && (shmflg&IPC_EXCL)!=0
EINVAL 要创建共享内存段,但size是无效的
EINVAL 没有共享内存段要创建,但size与系统设置的限制或与key所代表的共享段的长度不相符
ENOENT key的共享内存表示符不存在,但(shmflg&IPC_CREAT)== 0
ENOMEM 没有足够的内存空间来创建指定的共享内存段
ENOSPC 要超出系统范围内对共享标识符的限制了
功能:
shmget函数返回一个与参数key相关的共享内存段标识符。
如果键位IPC_CREAT或者shmflg&IPC_CREAT非零,而且没有共享内存段或标识符与key相关联,函数就创建这个段,共享内存段被初始化为零。
3. int shmctl(int shmid, int cmd, struct shmid_ds *buf);//共享内存的控制
成功返回0,不成功返回-1并设置errno,错误码:
EACCES cmd为IPC_STAT,但是调用程序没有读权限
EINVAL shmid或cmd的值无效
EPERM cmd为IPC_RMID或IPC_SET,调用程序没有正确的权限
cmd值:
IPC_RMID 删除共享内存段,并销毁相应的shmid_ds
IPC_SET 用buf中的值来设置共享内存段shmid的字段值
IPC_STAT 将共享内存段shmid中的当前值拷贝到buf中去
IPC_LOCK 将共享内存段锁定在内存中(只有超级用户可以执行)
IPC_UNLOCK 解锁共享内存
4.void *shmat(int shmid, const void *shmaddr, int shmflg);//共享内存段的连接
成功返回内存段的起始地址,不成功shmat返回-1并设置errno,必须检测的错误码:
EACCES 调用程序的操作权限别否定
EINVLA shmid和shmaddr的无效
EMFILE 连接到进程上的共享内存段的树木超出了限制
ENOMEM 进程数据空间不足以容纳共享内存段
功能:
函数将shmid指定的共享内存段连接到调用进程的地址空间,并为shmid增加shm_nattch的值。
如果shmaddr为0,则此段连接到由内核选择的第一个可用的地址上
如果shmaddr非0,并且没有指定SHM_RND,则此段连接到addr所指定的地址上
如果shmaddr非0,并且指定了SHM_RND,则此段连接到(addr-(addr mod ulus SHMLBA))所表示的地址上。
5. int shmdt(const void *shmaddr);//分离共享内存
成功返回0,不成功返回-1并设置errno,错误码:
EINVAL shmaddr不对应于共享内存段的起始地址
功能:
用完一个共享内存,调用其来分离共享内存段,并对shm_nattch进行减操作。
最后一个分离共享内存段的进程应该通过调用shmctl来释放共享内存段