获取进程
pid_t getpid()
功能:获取该进程的进程号。函数返回值为进程号。getppid()用来获取该进程父进程的进程号。
启动进程
pid_t fork()
功能:创建子进程。同时会有两个返回值。在子进程中返回0,在父进程中返回子进程的pid。若错误返回-1。并在父子进程中都运行该fork()语句后面的代码。
但我们可以用if (pid== 0) else if (pid > 0)判断来令父子进程执行不同的语句。
启动进程
pid _t vfork()
功能:创建子进程。与fork()相同。但是vfork的子进程要通过exit()来关闭,子进程不会自动关闭。
fork和 vfork的区别
1、 fork:子进程拷贝父进程的数据段,所以子进程和父进程代码相同,但是是各自独立的。
vfork:子进程与父进程共享数据段,所以在子进程上对变量进行修改,父进程也会被修改。(如,原来a = 1;子进程打印++a,父进程打印++a。那么子进程打印的值为2,父进程打印的值为3)。子进程中不能有return,因为return会释放空间,这是父进程运行时会报错(访问段错误)。
2、 fork:子进程和父进程的执行次序不确定
vfork:子进程先运行,父进程后运行。(子进程调用exit()或者exec后才会结束,这时候父进程开始运行)
pid_t wait(int*status)
功能:wait会停止目前进程的执行,直到有信号或者子进程结束才继续运行。返回值为子进程的进程识别码pid。同时,子进程的结束状态值会被放到status里,当然如果不需要status也可设置为NULL。如果此时子进程已经结束,则会立刻返回子进程的结束状态值。若发生错误,则返回-1.
pid_t waitpid(pid_tpid, int *statcu, int option);
功能:功能、status和返回值与wait相同。
参数: pid_t pid 为你需要等待的子进程的进程识别码。但也可以设置为如下4种:
1. pid<-1:等待进程识别码为pid的绝对值的任何子进程。
2. pid=-1:等待任何子进程,相当于wait().
3. pid=0:等待进程识别码与目前进程相同的任何子进程。
4. pid>0:等待进程识别码为pid的任何子进程。
int options可以为0或者以下几种的组合:
1. WNOHANG:如果没有任何已经结束的子进程,则马上返回,不等待
2. WUNTRACED:如果子进程进入暂停执行情况,则马上返回,结束状态不理会,但子进程结束状态符保存到status中。
进程退出
void exit(intstatus)
功能:正常终结目前进程,并把进程结束标识符存到status中返回给父进程。
管道通信
无名管道通信
int pipe(int filedes[2])
功能pipe()会建立管道,并将文件描述符用filedes数组返回。filedes[0]为读取端,filedes[1]为写入端。
返回值:成功返回0,否则返回-1
用法:1 pipe(fd[2])
2 父进程:write(fd[1], buf, 10);
3 子进程:read(fd[0], buf, 10)
有名管道通信
int mkfifo(constchar *pathname, mode_t mode)
功能:会依参数pathname创建FIFO文件(文件原先不存在),mode为文件的权限
用法:1mkfifo(FIFO, 0666)
2 父进程:open(FIFO, O_WRONLY);
write(fd, s, sizeof(s));
close(fd);
3 子进程:open(FIFO, O_RDONLY);
read(fd, s, sizeof(s));
close(fd);
信号通信
int kill(pid_tpid, int sig)
功能:把sig的信号传给pid的进程
参数:pid>0 把信号传给进程识别码为pid的进程
pid=0 把信号传给和目前进程相同进程组的所有进程
pid=-1把信号传给系统内所有的进程
pid<0 把信号传给进程组识别码为pid绝对值的信号
返回值:成功返回0,错误返回-1
int raise(int sig)
与kill函数相同,但是只能传给本进程。
unsigned intalarm(unsigned int seconds)
功能:设置信号SIGALRM,进过参数seconds指定的秒数后传送给目前进程,如果参数seconds为0,则取消设置的闹钟,并返回剩余的秒数。
返回值:返回之前闹钟剩余的秒数,如果之前未设闹钟,则返回0
void (* signal(intsignum, void (* handler)(int)))(int);
功能:signal会依照signum指定的信号设置该信号的处理函数,当指定信号到达时就会跳转调用参数handler指定的函数。
返回值:返回先前的信号处理好书指针,若错误,则返回SIG_ERR(-1)
int sigaction(intsignum, const struct sigaction *act, struct sigaction *(odlact);
功能:会依照参数signum指定的信号来处理函数。signum可以指定SIGKILL和SIGTOP以外的所有信号。
消息队列
key_t ftok(char*pathname, char proj);
功能:返回与路径pathname相对应的一个键值。该函数不直接对消息队列操作,但在调用ipc或msgget()来获得消息队列描述字前,往往要调用该函数。
返回值:返回与文件对应的键值
创建消息队列
int msgget(key_t,int msgflg)
功能:key是ftok得到的键值,msgflg是标志位。调用返回与键值key相对应的消息队列描述字。
在以下两种情况下,该调用将创建一个新的消息队列:
1如果没有消息队列与key的键值相对应,并且msgflg中包含了IPC_CREAT标志位
2 key参数为IPC_PRIVATE
返回值:成功返回消息队列描述字,失败返回-1.
读消息队列
int msgrcv(intmsqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg)
功能:调用从msgid代表的消息队列中读取一个消息,并把消息保存在msgp指向的msgbuf中。
参数:msqid为消息队列描述字,消息返回后存在msgbuf中。msgsz为消息内容的长度。msgtyp为请求读取的消息类型
写入数据
int msgsnd(intmsqid, struct msgbuf *msgp, int msgsz, int msgflg)
功能:向msgid发送一个信息,即将发送的信息储存在msgp指向的msgbuf结构中,消息的大小由msgze指定。
成功返回0,失败返回-1
消息队列:1 id= msgget
2 msgsnd
3 msgrcv
共享内存
创建共享内存
int shmget(key_tkey, int size, int shmflg)
功能:key标识共享内存的键值:0和IPC_PRIVATE.当key取值为IPC_PRIVATE,则函数shmget()将创建一块新的共享内存;如果key为0,而参数shmflg设置了IPC_PRIVATE,则同样会创建一块新的共享内存
返回值:成功返回共享内存标识符,失败返回-1。
映射共享内存
char *shmat(intshmid, char *shmaddr, int flag)
参数:shmid:shmget函数返回的共享内存标识符。
flag:映射的方式,通常为0
返回值:成功返回0,失败返回-1
用法:1 id = shmget
2进程1 p_addr = shmat(id, , )
3进程2 a_addr = shmat(id, , )
多线程编程
进程:资源分配的最小单位
线程:程序执行的最小单位
同一进程内的线程共享进程的地址空间
因为pthread的库不是Linux系统的库,所以在进行编译的时候要加上 -lpthread
创建线程
int pthread_create(pthread_t*restrict tidp, const pthread_addr_t *restrict attr, void *(*start_rtn)(void),void *restrict arg)
参数:pthread_t*restrict tidp:要创建的线程的线程ID指针
constpthread_addr_t *restrict attr:创建线程是的线程属性
void*(*start_rtn)(void):返回值是void类型的指针函数
void *restrict arg:start——rtn的形参
返回值:成功返回0,失败返回特定值。
等待线程中止
intpthread_join(thread_t tid, void **status)
说明:tid指定要等待的线程ID,指定的线程必须位于当前的进程中。当参数tatus不是NULL时,status指向某个位置,在pthread_join()成功返回时,将该位置设置为已终止线程的退出状态。
返回值:成功返回0,失败返回特定值