1.进程的创建
#include<myhead.h>
int main(int argc, const char *argv[])
{
printf("hello world\n");//父进程执行的内容
int num=520;//在父进程中定义的变量
pid_t pid=fork();//创建子进程
if(pid>0)
{
while(1)
{
printf("我是父进程,num=%d\n",num);
sleep(1);
}
}
else if(pid==0)
{
num=1314;//更改子进程中的num的值
while(1)
{
printf("我是子进程,num=%d\n",num);
sleep(1);
}
}else
{
perror("fork error");
return -1;
}
return 0;
}
2.进程号的获取
#include<myhead.h>
int main(int argc, const char *argv[])
{
pid_t pid=-1;
//创建一个子进程
pid=fork();
//判断父子进程
if(pid>0)
{
printf("我是父进程,当前进程id号:%d,ppid=%d\n",getpid(),getppid());
}
else
{
printf("我是子进程,当前进程id号:%d,ppid=%d\n",getpid(),getppid());
}
while(1);
return 0;
}
3.回收进程资源wait
#include<myhead.h>
int main(int argc, const char *argv[])
{
pid_t pid=-1;
//创建一个子进程
pid=fork();
//判断父子进程
if(pid>0)
{
printf("我是父进程,当前进程id号:%d,ppid=%ildid=%d\n",getpid(),getppid(),pid);
//调用进程退出函数
//exit(EXIT_SUCCESS);//会刷新缓冲区
//_exit(EXIT_SUCCESS);//不会刷新缓冲区
}
else
{
printf("我是子进程,当前进程id号:%d,ppid=%d\n",getpid(),getppid());
sleep(3);
exit(EXIT_SUCCESS);//会刷新缓冲区
}
wait(NULL);//阻塞等待子进程结束
printf("已经成功回收子进程\n");
while(1);
return 0;
}
4.waitpid回收僵尸进程
#include<myhead.h>
int main(int argc, const char *argv[])
{
pid_t pid=fork();//创建子进程
if(pid>0)
{
printf("我是父进程\n");
//sleep(5);
}
else if(pid==0)
{
printf("我是子进程\n");
sleep(3);
//退出子进程
exit(EXIT_SUCCESS);
}
else
{
perror("fork error");
return -1;
}
//使用waitpid以非阻塞的形式回收僵尸进程
if(waitpid(-1,NULL,WNOHANG)>0)
{
printf("成功回收一个僵尸进程\n");
}
printf("父进程要结束了\n");
return 0;
}
5.使用多进程完成两个文件的拷贝,父进程拷贝前一半,子进程拷贝后一半,父进程回收子进程资源。
#include<myhead.h>
//定义获取文件长度的函数
int get_file_len(const char *srcfile,const char *destfile)
{
//以只读的形式打开源文件
int srcfd,destfd;
if((srcfd=open(srcfile,O_RDONLY))==-1)
{
perror("open srcfile error");
return -1;
}
//以只写和创建的形式打开目标文件
if((destfd=open(destfile,O_WRONLY|O_CREAT|O_TRUNC,0664))==-1)
{
perror("open destfile error");
return -1;
}
//求源文件的大小
int len=lseek(srcfd,0,SEEK_END);
//关闭两个文件
close(srcfd);
close(destfd);
return len;
}
//定义文件拷贝函数
int copy_file(const char *srcfile,const char *destfile,int start,int len)
{
//以只读的形式打开源文件,以只写的形式打开目标文件
int srcfd,destfd;
if((srcfd=open(srcfile,O_RDONLY))==-1)
{
perror("srcfile open error");
return -1;
}
if((destfd=open(destfile,O_WRONLY))==-1)
{
perror("destfile open error");
return -1;
}
//移动文件的光标
lseek(srcfd,start,SEEK_SET);
lseek(destfd,start,SEEK_SET);
//完成拷贝工作
char buf[128]="";
int sum=0;
while(1)
{
int res=read(srcfd,buf,sizeof(buf));
sum+=res;//将每次读取的数据放入sum中
if(sum>=len||res==0)
{
write(destfd,buf,res-(sum-len));//将最后一次的内容写入
break;
}
//将读取的数据写入目标文件
write(destfd,buf,res);
}
//关闭文件
close(srcfd);
close(destfd);
return 0;
}
int main(int argc, const char *argv[])
{
//判断外部传参
if(argc!=3)
{
printf("input file error\n");
printf("usage:./a.out srcfile destfile\n");
return -1;
}
//定义变量获取源文件长度
int len=get_file_len(argv[1],argv[2]);
//创建多进程
pid_t pid=fork();
//皮带父子进程
if(pid>0)
{
//父进程
copy_file(argv[1],argv[2],0,len/2);//父进程拷贝前一半
//阻塞等待子进程结束
wait(NULL);
}
else if(pid==0)
{
//子进程
copy_file(argv[1],argv[2],len/2,len-len/2);//子进程拷贝后一半
//退出进程
exit(EXIT_SUCCESS);
}
else
{
perror("fork error");
return -1;
}
printf("拷贝成功\n");
return 0;
}
6.守护进程的创建
#include<myhead.h>
int main(int argc, const char *argv[])
{
//创建子进程
pid_t pid=-1;
pid=fork();
//判断
if(pid>0)
{
//父进程
exit(EXIT_SUCCESS);
}
else if(pid==0)
{
//子进程
//1.将组id和会话id改成自己
setsid();
//2.更改操作目录为根目录
chdir("/");
//3.修改创建文件的掩码
umask(0);
//4.将标准输入、标准输出和标准出错重定向到指定文件
int fd=-1;
if((fd=open("./logtest.txt",O_RDWR|O_CREAT|O_APPEND))==-1)
{
perror("open error");
return -1;
}
dup2(fd,0);
dup2(fd,1);
dup2(fd,2);
while(1)
{
printf("hello world\n");
fflush(stdout);//刷新缓冲区
sleep(1);
}
}
else
{
perror("fork error");
return -1;
}
return 0;
}
7.创建多线程
#include<myhead.h>
//定义分之线程
void *task(void *arg)
{
while(1)
{
printf("我是分支线程\n");
sleep(1);
}
}
int main(int argc, const char *argv[])
{
//定义一个线程号变量
pthread_t tid=-1;
//创建线程
if((pthread_create(&tid,NULL,task,NULL))!=0)
{
printf("pthread_creat error\n");
return -1;
}
//下面的程序是主线程内容
while(1)
{
printf("我是主线程,tid=%ld\n",tid);
sleep(1);
}
return 0;
}
8.多线程的综合应用
#include<myhead.h>
//定义分支线程
void *task(void *arg)
{
while(1)
{
printf("我是分支线程,tid=%#lx\n",pthread_self());
sleep(3);
//退出线程
pthread_exit(NULL);
printf("111111111111111\n");
}
}
int main(int argc, const char *argv[])
{
//定义一个线程号变量
pthread_t tid=-1;
//创建线程
if((pthread_create(&tid,NULL,task,NULL))!=0)
{
printf("pthread_create error\n");
return -1;
}
//下面的程序是主线程的内容
printf("我是主线程,tid=%#lx,主线程号:%#lx\n",tid,pthread_self());
//回收线程退出的资源,阻塞等待对应的线程退出
if(pthread_join(tid,NULL)==0)
{
printf("成功回收了一个线程\n");
}
//将线程设置程分离态
pthread_detach(tid);
printf("主线程要退出了\n");
sleep(5);
return 0;
}
9.向指定线程发送取消信号
#include<myhead.h>
//定义分支线程1
void *task1(void *arg)
{
while(1)
{
printf("我是线程1,我想活着\n");
sleep(1);
}
}
//定义分支线程2
void *task2(void *arg)
{
while(1)
{
//设置忽略取消信号
if(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL)!=0)
{
printf("set error\n");
return NULL;
}
printf("我是线程2,我想活着\n");
sleep(1);
}
}
int main(int argc, const char *argv[])
{
//定义线程号变量
pthread_t tid1,tid2;
//创建两个线程
if(pthread_create(&tid1,NULL,task1,NULL)!=0)
{
printf("pthread_create tid1 error\n");
return -1;
}
if(pthread_create(&tid2,NULL,task2,NULL)!=0)
{
printf("pthread_create tid2 error\n");
return -1;
}
//主线程
printf("tid1=%#lx,tid2=%#lx\n",tid1,tid2);
sleep(5);
printf("线程1可以死了\n");
pthread_cancel(tid1);
sleep(5);
printf("线程2也可以死了\n");
pthread_cancel(tid2);
//回收线程资源
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
return 0;
}
10.向分支线程中传递数据
#include<myhead.h>
//定义要传递的结构体类型
struct Info
{
char *p;
char *q;
int s;
int l;
int value;
};
//定义全局变量
int key=1314;
//定义分支线程
void *task(void *arg)
{
printf("key=%d\n",++key);
//处理主线程中传过来的数据
struct Info buf=*((struct Info*)arg);
printf("buf.p=%s,buf.q=%s,buf.s=%d,buf.l=%d\n",buf.p,buf.q,buf.s,buf.l);
//想要将分支线程中的数据传给主线程
(*((struct Info*)arg)).value=5201314;
}
int main(int argc, const char *argv[])
{
pthread_t tid;
int num=520;
//要传递给分支线程的数据
char *srcfile="./02text.txt";
char *destfile="./17test.txt";
int start=0;
int len=520;
//定义一个结构体变量
struct Info buf={srcfile,destfile,start,len};
//创建线程
if(pthread_create(&tid,NULL,task,&buf)!=0)//向分支线程传递一个数据
{
printf("tid create error\n");
return -1;
}
//主线程中使用全局变量
printf("key=%d\n",++key);
sleep(1);
//输出分支线程给的数据
printf("buf.value=%d\n",buf.value);
//回收资源
pthread_join(tid,NULL);
return 0;
}
11.使用多线程完成两个文件的拷贝,第一个线程拷贝前一半,第二个线程拷贝后一半,主线程回收两个线程的资源。
#include<myhead.h>
//创建结构体用于主线程往分支线程传参
typedef struct Info
{
int length;
const char *src;
const char *dest;
}SI;
int get_file_len(const char *srcfile,const char *destfile);
int copy_file(const char *srcfile,const char *destfile,int start,int len);
//创建子线程1
void *task1(void *arg)
{
copy_file(((SI *)arg)->src,((SI *)arg)->dest,0,((SI *)arg)->length/2);//子线程1拷贝前一半
pthread_exit(NULL);//退出线程
}
//创建子线程2
void *task2(void *arg)
{
copy_file(((SI *)arg)->src,((SI *)arg)->dest,((SI *)arg)->length/2,((SI *)arg)->length-((SI *)arg)->length/2);//子线程2拷贝后一半
pthread_exit(NULL);//退出线程
}
int main(int argc, const char *argv[])
{
//判断外部传参是否合法
if(argc!=3)
{
printf("input file error\n");
printf("usage:./a.out srcfile destfile\n");
return -1;
}
//定义变量获取源文件的长度
int len=get_file_len(argv[1],argv[2]);
//定义结构体并初始化
SI *file=(SI *)malloc(sizeof(struct Info));
file->length=len;
file->src=argv[1];
file->dest=argv[2];
//定义两个线程号变量
pthread_t tid1,tid2;
//创建线程
if(pthread_create(&tid1,NULL,task1,file)!=0)
{
perror("tid1 create error\n");
return -1;
}
if(pthread_create(&tid2,NULL,task2,file)!=0)
{
perror("tid2 create error\n");
return -1;
}
//回收资源
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
//释放结构体内存
free(file);
file=NULL;
return 0;
}
//定义获取文件长度的函数
int get_file_len(const char *srcfile,const char *destfile)
{
//以只读的形式打开源文件
int srcfd,destfd;
if((srcfd=open(srcfile,O_RDONLY))==-1)
{
perror("srcfile open error\n");
return -1;
}
//以只写和创建的形式打开目标文件
if((destfd=open(destfile,O_WRONLY|O_CREAT|O_TRUNC,0664))==-1)
{
perror("destfile open error\n");
return -1;
}
//求源文件的大小
int len=lseek(srcfd,0,SEEK_END);
//关闭两个文件
close(srcfd);
close(destfd);
return len;
}
//定义文件拷贝函数
int copy_file(const char *srcfile,const char *destfile,int start,int len)
{
int srcfd,destfd;
//以只读的形式打开源文件,以读写的形式打开目标文件
if((srcfd=open(srcfile,O_RDONLY))==-1)
{
perror("srcfile open error\n");
return -1;
}
if((destfd=open(destfile,O_RDWR))==-1)
{
perror("destfile open error\n");
return -1;
}
//移动文件的光标
lseek(srcfd,start,SEEK_SET);
lseek(destfd,start,SEEK_SET);
//完成拷贝工作
char buf[128]="";//定义搬运工
int sum=0;//用于累计搬运的大小
while(1)
{
int res=read(srcfd,buf,sizeof(buf));
sum+=res;//将每次读取的数据放入到sum中
if(sum>=len||res==0)
{
write(destfd,buf,res-(sum-len));//将最后一次搬运的内容写入
break;
}
//将读取的数据写入目标文件
write(destfd,buf,res);
}
//关闭文件
close(srcfd);
close(destfd);
}