Linux下进程学习及多线程copy样例

这篇博客详细介绍了进程的基本概念,如进程的状态、标识符和特性,并讨论了进程互斥和死锁的问题。文章通过一个C语言示例展示了如何使用fork函数创建子进程来实现文件的多段复制,解释了在父进程先于子进程结束时,子进程会成为孤儿进程并由init进程领养。此外,还解释了getpid和getppid函数的作用。
摘要由CSDN通过智能技术生成

程序是放到磁盘的可执行文件
进程是指程序执行的实例
进程是一个具有一定独立功能的程序的一次运行活动
进程是一个程序正在执行的实例。每个这样的实例都有自己的地址空间和执行状态

进程三种状态:执行就绪阻塞(类似于scanf函数)

进程ID(PID):标识进程的唯一数字
父进程ID(PPID)
启动进程的用户ID(UID)

进程特点:动态性(执行过程,动态的);
    并发性(可以同时几个进程);
    独立性(独立运行,系统分配资源的独立单位);
    异步性(相互制约,执行间断,各自独立,速度不是同步的,故异步);
    结构特性(程序数据进程控制块三部分);

进程互斥:若干进程都要使用某一资源时,任何时候最多只能允许一个进程使用,
    其他要使用该资源的进程必须等待知道该资源释放。

进程死锁:多个进程因竞争资源而形成一种僵局,若无外力作用,
    这些进程都将无法向前推进

pid_t fork(viod)
功能:创建子进程
    fork调用一次,返回两次,有三种不同的返回值:
1、在父进程中,fork返回新创建的子进程的PID;
2、在子进程中,fork返回0;
3、如果出现错误,fork返回一个负值。

getpid()是获取当前进程的pid
getppid()是获取当前进程的父进程的pid(在父进程中获取的不是自己的进程)

当父进程在子进程前挂掉会出现什么情况?
子进程会变成孤儿进程,此时该子进程会被init进程领养。(当前进程的父进程id可能是1)

子进程有父进程,父进程也有父进程,然最开始的进程是谁?
init进程,也是ID为1,当系统开启就会存在。

实现多进程的copy样例

#include <stdio.h>
#include <sys/types.h> 
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    int num = 5, i, ret;
    int fd_from = open(argv[1], O_RDONLY);
    if (-1 == fd_from)
    {
        perror("open");
        exit(1);
    }

    //计算源文件长度
    int length = lseek(fd_from, 0, SEEK_END);
    int each_len = length / num;
    close(fd_from);

    int fd_to = open(argv[2], O_WRONLY | O_CREAT, 00700);
    if (-1 == fd_to)
    {
        perror("open2");
        exit(2);
    }
    close(fd_to);

    pid_t pid;

    for (i = 1; i <= num; i++)
    {
        pid = fork();
        if (-1 == pid)
        {
            perror("fork");
            exit(1);
        }
        else if (0 == pid)
        {
            break;
        }
    }

    int byte_count = 0;
    char buf[128] = {0};
    
    if ( i == num + 1) //父进程
    {
        //回收zi进程
        printf("父进程\n");
    }
    else if(i == 5)
    {
        fd_from = open(argv[1], O_RDONLY);
        if (-1 == fd_from)
        {
            perror("open1");
            exit(1);
        }
        
        fd_to = open(argv[2], O_WRONLY);
        if (-1 == fd_to)
        {
            perror("open2");
            exit(2);
        }
        lseek(fd_from, (i - 1) * each_len, SEEK_SET);//将指针移到第四个进程结束的地方
        lseek(fd_to, (i - 1) * each_len, SEEK_SET);
    
        while(1)
        {
            ret = read(fd_from, buf, sizeof(buf) - 1);
            if (-1 == ret)
            {
                perror("read");
            }
            else if (0 == ret)
            {
                printf("the fifth process copy over!\n");
                break;
            }

            ret = write(fd_to , buf, ret);
            if (-1 == ret)
            {
                perror("write");
            }
            memset(buf, 0, sizeof(buf));
                
        }
        close(fd_to);
        close(fd_from);
    }


    else
    {
        fd_from = open(argv[1], O_RDONLY);
        if (-1 == fd_from)
        {
            perror("open1");
            exit(1);
        }
        
        fd_to = open(argv[2], O_WRONLY);
        if (-1 == fd_to)
        {
            perror("open2");
            exit(2);
        }
        
        lseek(fd_from, (i - 1) * each_len, SEEK_SET);
        lseek(fd_to, (i - 1) * each_len, SEEK_SET);

        while(1)
        {
            if (each_len - byte_count < sizeof(buf) - 1)
            {
                ret = read(fd_from, buf, each_len - byte_count);
                if (-1 == ret)
                {
                    perror("read");
                }
            }
            else
            {
                ret = read(fd_from, buf, sizeof(buf) - 1);
                if (-1 == ret)
                {
                    perror("read");
                }
            }
            byte_count += ret;

            ret = write(fd_to, buf, ret);
            if (-1 == ret)
            {
                perror("write");
            }
            if (byte_count == each_len)
            {
                printf("the %d copy over\n", ret);
                break;
            }
        }
        close(fd_to);
        close(fd_from);
        memset(buf, 0, sizeof(buf));
    }

    return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值