标签:
pid_t fork(void)
fork()被调用一次,却返回两次,可能的返回值:
1.在父进程中,fork 返回新创建的子进程的的 PID
2.在子进程中,fork 返回零
3.如果出现错误, fork 返回一个负值
子进程被创建之后,会从 fork()之后的代码开始运行,而不会重复运行父进程运行过的代码,
int main(int argc,char*argv)
{
pid_t pid;
pid = fork();// 创建进程之后,父子进程,都是从这边开始去执行代码
if(pid <0)
printf("error\n");
elseif(pid ==0)
printf("child PID = %d\n", getpid());
else
printf(" PPID = %d\n", getppid());
return0;
}
pid_t vfork(void)也是创建子进程,
int execl(constchar*path,constchar*arg1,,,,)
path :被指定的程序名字,包含完整的路径
arg1 - argn 被指定的程序所需的命令行的参数,以空指针(NULL)结束。
int execlp(constchar*path,constchar*arg1,,,,)
path :被执行的程序名,这个是不包含路径的哦,
argv :被指定的命令行参数,还是以空指针,NULL ,结束
int execlv(constchar*path,constchar*argv[])
path :被执行的程序名,包含完整的路径
argv :被指定的命令行参数,是包含在数组里面
int system(constchar*string )
调用 fork 产生子进程,由子进程来调用/bin/sh -c string 来执行 string 所代表的命令
pid_t wait(int*status )
阻塞该进程,让它一直等待,知道他的某个子进程退出,
int main(int argc,char**argv)
{
pid_t pc, pr;
// 创建进程
pc = fork();
if(0== pc)
{
printf("这是子进程,进程号是 : %d\n", getpid());
sleep(10);
}
elseif(pc >0)
{// 保证是子进程运行之后,再运行父进程,
pr = wait(NULL);
printf("这是父进程,进程号是 : %d\n", getppid());
}
return0;
}
创建管道:
int pipe(int filedis[2]);
#define INPUT 1
#define OUTPUT 0
void main(){
int file_descriptors[2];
/*定义子进程号 */
pid_t pid;
char buf[256];
int returned_count;
/*创建无名管道*/
pipe(file_descriptors);
/*创建子进程*/
if((pid = fork())==-1){
printf("Error in fork/n");
exit(1);
}
/*执行子进程*/
if(pid ==0){
printf("in the spawned (child) process.../n");
/*子进程向父进程写数据,关闭管道的读端*/
close(file_descriptors[INPUT]);
write(file_descriptors[OUTPUT],"test data", strlen("test data"));
exit(0);
}else{
/*执行父进程*/
printf("in the spawning (parent) process.../n");
/*父进程从管道读取子进程写的数据,关闭管道的写端*/
close(file_descriptors[OUTPUT]);
returned_count = read(file_descriptors[INPUT], buf,sizeof(buf));
printf("%d bytes of data received from spawned process: %s/n",
returned_count, buf);
}
}
int mkfifo(constchar*pathname,mode_t mode)
pathname : FIFO 文件名,实质上,就是文件名嘛。
mode :属性,
实质上,命名管道,就是一个文件,两个进程之间的通信,实质就是通过一个文件,进行通信
read.c:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
char buf[100];
int fd;
int by;
// 创建管道
mkfifo("FIFO", O_CREAT | O_RDONLY);
// 清零
memset(buf,0,sizeof(buf));
// 打开管道,其实就是文件拉,
fd = open("FIFO", O_RDONLY | O_NONBLOCK);
if(fd ==-1)
{
printf(" failed to open\n");
exit(-1);
}
while(1)
{// 循环,读取,循环清零
memset(buf,0,sizeof(buf));
if((by = read(fd, buf,100))==-1)
{
printf("no data\n ");
}
printf("read %s \n", buf);
sleep(1);
}
return0;
}
write.c:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(int argc,char*argv)
{
char buf[100];
int fd;
int by;
if(argc <2)
{
printf("give moer inf \n");
exit(-1);
}
// 清零
memset(buf,0,sizeof(buf));
// 打开管道,其实就是文件拉,
fd = open("FIFO", O_RDONLY | O_NONBLOCK);
if(fd ==-1)
{
printf(" failed to open\n");
exit(-1);
}
// 将输入的字符串,拷贝给 buf
strcpy(bufm argv[1]);
if((by = write(fd, buf,100))==-1)
{
printf("error\n");
}
else
{
printf("FIFO is %s \n", buf);
}
return0;
}
int kill(pid_t pid,int signo)
kill 可以给自己,也可以给其他的进程发送信号
pid :指定发送信号的进程号,就把 signo 发送给指定的进程
int raise(int signo)
raise 只能给进程的自身发送信号,自己给自己发,所以不需要 PID
unsignedint alarm(unsignedint seconds)
指定了当经过 seconds 秒之后,就会自己给自己发送一个 SIFALRM 信号
int pause(void)
使进程等待,一直等到接收到一个信号为止,才不在等待
信号的处理
接收到信号,要么忽略,要么按照指定的函数执行,要么就按照默认的方式去进行处理
void(*signal(int signo,void(*func)(int)))(int)
func :
SIG_IGN :忽略信号
SIG_DFL :按照默认的方式去处理
信号处理的函数名:指定函数,传入的参数,就是信号比如 SIGINT
返回值:还是一个函数的指针,
void func(int sign_no)
{
if(sign_no == SIGINT)
printf("signal is SIGINT\n");
if(sign_no == SIGQUIT)
printf("signal is SIGQUIT\n");
}
int main(int argc,char** argv)
{
// 注册信号处理的函数
signal(SIGINT, func);
signal(SIGQUIT, func);
// 注册好之后,会一直等待,知道有参数进来
pause();
return0;
}
kill - s +信号+ PID
int shmget(key_t key,int size,int shmflg)
key:内存创建的标志,0/ IPC_PRIVATE,IPC_PRIVATE,表示创建新的共享的内存,
size :创建的大小,以字节为单位
成功创建的话,返回内存的标识符,错误就为-1
int shmat(int shmid,char*shmaddr,int flag )
shmid :是shmget 函数返回的光纤内存的标识符
flag :一般是零
shmaddr :获取值,获得共享内存的地址,一般为零,让系统分配
成功的话,返回地址,失败的话,返回值为-1
char *shmdt(char*shmaddr)
char*c_addr,*p_addr;
int shmid;
// 分配内存
shmid = shmget(IPC_PRIVATE,1024, S_IRUSR | S_IWUSR);
if(fork())
{// 获得映射的地址
p_addr = shmat(shmid,0,0);
memset(p_addr,0,1024);
strncpy(p_addr, argv[1],1024);
// 等待,子进程结束
wait(NULL);
exit(0);
}
else
{// 保证父进程先执行
sleep(2);
// 获得映射的地址
c_addr = shmat(shmid,0,0)
printf(" get %s \n", c_addr);
}
(1)信号量的初始化
DEFINE_SEMAPHORE(semaphore_lock)// 一步完成信号量的定义和初始化,此时的信号量设置为1,也就是为互斥锁
// 也可以,分开来,不过比较麻烦,不过是一样的作用
staticstruct semaphore sem;// 信号量的定义
sema_init(struct semaphore * sem,int val);// 信号量的初始化
(2)获得信号量
void down(struct semaphore *sem)// 获得信号量,其实做减一,当为零的时候,进程就好休眠
int down_interruptible(struct semaphore * sem)
int down_trylock(struct semaphore * sem)// 三种获得信号量的区别,这里不做详解
(3)释放信号量
void up(struct semaphore *sem)// 其实就是做加一的动作,将信号量的值加一
标签:
原文地址:http://www.cnblogs.com/qxj511/p/4917710.html