C/C++网络编程7——多进程服务器端之fork函数

  通过前面几节的内容,我们已经可以实现基本的C/S结构的程序了,但是当多个客户端同时向服务器端请求服务时,服务器端只能按顺序一个一个的服务,这种情况下,客户端的用户是无法忍受的。所以虚实现并发的服务器端。

并发服务器端的实现方法:

  1:多进程服务器端:通过创建多个进程提供服务。

  2:多路复用服务器:用过捆绑并统一管理I/O对象提供服务。

  3:多线程服务器:通过生成与客户端等量的线程提供服务。

多进程服务器端:

  进程:可执行程序的一次执行过程。

  在linux下可通过fork()函数创建一个进程。

#include <unistd.h>

pid_t fork(void)
// 成功返回时父进程返回子进程的id,子进程返回0,失败时返回-1

  通过fork()函数创建进程以后,父进程和子进程拥有完全独立的内存空间。举例:

#include <iostream>
#include <unistd.h>

using namespace std;

int g_count = 10;

int main()
{
    int l_count = 20;
    g_count++;
    l_count++;

    pid_t pid = fork();

    if (pid < 0) {
        cout << "fork() failed" << endl;
        return 0;
    }

    if (pid == 0) {
        g_count += 5;
        l_count += 5;
    } else {
        g_count -= 5;
        l_count -= 5;
    }

    if (pid == 0) {
        cout << "child: " << g_count <<" " << l_count << endl;
    } else {
        cout << "parent: " << g_count <<" " << l_count << endl;
    }

    return 0;
}

僵尸进程及孤儿进程:

  僵尸进程:子线程执行结束以后,系统资源不会被操作系统回收,需等父进程执行结束时回收,但父进程没执行结束,此时的子进程就成了僵尸进程。

  孤儿进程:父进程已经执行结束,子进程还没执行结束,这时的子进程成为孤儿进程。孤儿进程执行结束以后系统资源有pid=1的进程回收。

  僵尸进程的系统资源迟迟得不到回收会导致系统资源被耗尽,所以需要避免僵尸进程。孤儿进程不会造成资源不被回收,可不处理。

  僵尸进程产生举例:

#include <iostream>
#include <unistd.h>

using namespace std;

int main()
{
    pid_t pid = fork();

    if (pid < 0) {
        cout << "fork() failed" << endl;
        return 0;
    }

    if (pid == 0) {
        cout << "i am child proc: " << getpid() << endl;
    } else {
        cout << "i am parent proc: " << getpid() << endl;
        sleep(60);
    }

    return 0;
}

原文地址:https://www.cnblogs.com/418ks/p/11717113.html

时间: 2024-08-05 21:55:19

C/C++网络编程7——多进程服务器端之fork函数的相关文章

c网络编程(server服务器端,linux)

多进程 1 #include "network.h" 2 3 void do_service(int peerfd) 4 { 5 char recvbuf[1024] = {0}; 6 int ret; 7 while(1) 8 { 9 ret = readline(peerfd, recvbuf, 1024); 10 if(ret == 0) 11 { 12 close(peerfd); 13 exit(EXIT_SUCCESS); 14 } 15 //模拟数据处理过程 16 pri

网络编程中的read,write函数

关于TCP/IP协议,建议参考Richard Stevens的<TCP/IP Illustrated,vol1>(TCP/IP详解卷1). 关于第二层面,依然建议Richard Stevens的<Unix network proggramming,vol1>(Unix网络编程卷1),这两本书公认是Unix网络编程的圣经. 至于第三个层面,UNP的书中有所提及,也有著名的C10K问题,业界也有各种各样的框架和解决方案,本人才疏学浅,在这里就不一一敷述. 本文的重点在于第二个层面,主要

深入浅出--UNIX多进程编程之fork()函数

0前言 上周都在看都在学习unix环境高级编程的第八章--进程控制.也就是这一章中,让我理解了unix中一些进程的原理.下面我就主要按照进程中最重要的三个函数来进行讲解.让大家通过阅读这一篇文章彻底明白进程这点事.希望对大家有所帮助. 1进程环境 在学习进程之前,一定要了解一下unix的进程环境.系统如何对进程终止,和一个程序启动终止,程序运行的原理等,这些都有助于你理解进程的运行原理.这些内容都在我的上一篇文章中,请关注:http://blog.csdn.net/wallwind/articl

Git的使用及网络编程多线程多进程

Git的使用 1.打开CMD命令行,输入cd Desktop进入桌面 2.输入 mkdir + 'file name'创建文件,如果已有项目则输入 cd + file name进入文件,如果在Git上已有项目并且在已有项目进行修改,则输入cd clone + url 3.如果第一次使用,则先初始化,git init 4. git add + file name 把项目加入文件夹里面 5.git config -global 全局设置(第一次使用的时候设置) 6. git log 查看日志.git

网络编程readn、writen和readline函数的编写

readn   在Linux中,read的声明为: ssize_t read(int fd, void *buf, size_t count); 它的返回值有以下情形: 1.大于0,代表成功读取的字节数 2.等于0,代表读取到了EOF,一般是对方关闭了socket的写端或者直接close 3.小于0,出现错误. 我们编写一个readn函数,声明与read一致,但是,readn在未出错或者fd没有关闭的情况下,会读满count个字节. ssize_t readn(int fd, void *buf

【Linux编程】进程标识符与fork函数

ID为0的进程一般是调度进程.常被称为交换进程(swapper),是内核中的系统进程. ID为1的进程叫做init进程,是一个普通用户进程,不属于内核,由内核调用. 一个现有进程能够调用fork函数创建一个新进程(子进程).fork函数被调用一次.返回两次. 子进程返回值为0.父进程返回值为子进程的进程ID. 当fork出一个子进程后,子进程便拥有独立的数据段.堆.栈的副本,但父.子进程共享正文段(关于程序分布见文章"C程序的存储空间布局").但如今非常多实现并不全然复制数据段.堆.栈

Java网络编程 - 客户端向服务器端发送文件的简单实现

1.Client package cn.qi.Client; import java.io.*; import java.net.Socket; public class Client { Socket clientSocket; Client() { // 建立连接到服务器端的socket try { clientSocket = new Socket("127.0.0.1", 5000); } catch (IOException e) { e.printStackTrace();

python 网络编程-02 多进程的交互案例

server.py import socket from threading import Thread def Server(): server = socket.socket() server.bind(('127.0.0.1', 8000)) server.listen(5) while True: conn, addr = server.accept() Thread(target=talk,args=[conn,]).start() def talk(connect): while T

Erlang网络编程中的一个特别的函数prim_inet:async_accept/2(转)

为了研究怎么用Erlang写一个游戏服务器,我很幸运的下到了一份英雄远征的服务器Erlang源码,这两天花了点时间看代码,其中看到做TCP的accept动作时,它是用的一个函数prim_inet:async_accept/2,这个可跟书上说的不一样(一般来说书上教的是用gen_tcp:accept/1),于是我google了一下,发现找不到文档,再翻一下发现已经有不少人问为什么这是一个undocumented的函数,也就是说Erlang就没想让你去用这个函数,所以文档自然没提供.一般来说undo