關於linux多線程fork的理解和學習

来源:https://www.cnblogs.com/dhua/archive/2022/05/14/16271364.html
-Advertisement-
Play Games

一、概述 Scala是一門多範式的編程語言,一種類似java的編程語言 ,設計初衷是實現可伸縮的語言 、並集成面向對象編程和函數式編程的各種特性。Spark就是使用Scala編寫的。因此為了更好的學習大數據開發, 需要掌握Scala這門語言,當然Spark的興起,也帶動Scala語言的發展!官方文檔 ...


  fork在英文中是“分叉”的意思。為什麼取這個名字呢?因為一個進程在運行中,如果使用了fork函數,就產生了另一個進程,於是進程就“分叉”了,所以這個名字取得很形象。下麵就看看如何具體使用fork函數,這段程式演示了使用fork的基本框架。   函數聲明:   pid_t fork();     fork函數用於產生一個新的進程,函數返回值pid_t是一個整數,在父進程中,返回值是子進程編號,在子進程中,返回值是0。  
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
 
int main()
{
  printf("本程式的進程編號是:%d\n",getpid());
 
  int ipid=fork();
 
  sleep(1);       // sleep等待進程的生成。
 
  printf("pid=%d\n",ipid);
 
  if (ipid!=0) printf("父進程編號是:%d\n",getpid());
  else printf("子進程編號是:%d\n",getpid());
 
  sleep(30);    // 是為了方便查看進程在shell下用ps -ef|grep book252查看本進程的編號。
}
    從 fork() 這個函數開始出現後, 便創建了子進程,並且子進程和父進程一樣從fork(這個函數一起執行下去,也就是說從fork()開始的下麵所有代碼分別被父 進程和子進程都執行了一次,如果沒有條件判斷語句判別fork()的返回值,將無法分別子父進程,根據fork()的返回值可以令子父進程跳過或執行某條語句

運行結果

 

 

初學者可能用點接受不了現實。

1)一個函數(fork)返回了兩個值?

2)if和else中的代碼能同時被執行?

那麼調用這個fork函數時發生了什麼呢?fork函數創建了一個新的進程,新進程(子進程)與原有的進程(父進程)一模一樣。子進程和父進程使用相同的代碼段;子進程拷貝了父進程的堆棧段和數據段。子進程一旦開始運行,它複製了父進程的一切數據,然後各自運行,相互之間沒有影響。

fork函數對返回值做了特別的處理,調用fork函數之後,在子程式中fork的返回值是0,在父進程中fork的返回是子進程的編號,程式員可以通過fork的返回值來區分父進程和子進程,然後再執行不同的代碼。

 

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

void fatchfunc() // 父進程流程的主函數
{
  printf("我是老子,我喜歡孩子他娘。\n");
}

void childfunc() // 子進程流程的主函數
{
  printf("我是兒子,我喜歡西施。\n");
}

int main()
{
  if (fork() > 0)
  {
    printf("這是父進程,將調用fatchfunc()。\n");
    fatchfunc();
  }
  else
  {
    printf("這是子進程,將調用childfunc()。\n");
    childfunc();
  }

  sleep(1);
  printf("父子進程執行完自己的函數後都來這裡。\n");
  sleep(1);
}

 

 

運行結果:

 

 

在上文上已提到過,子進程拷貝了父進程的堆棧段和數據段,也就是說,在父進程中定義的變數子進程中會複製一個副本,fork之後,子進程對變數的操作不會影響父進程,父進程對變數的操作也不會影響子進程。

 

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
 
int i=10;
 
int main()
{
  int j=20;
 
  if (fork()>0)  //從 fork() 這個函數開始出現後,
                  //便創建了子進程並且和父進程一樣從fork()
                  //這個函數一起執行下去,也就是說從fork()開始的下麵所有代碼分別被父///進程和子進程都執行了一次,如果沒有條件判斷語句判別fork()的返回/////值,將無法分別子父進程,根據fork()的返回值可以令子父進程跳過或執///行某條語句

  {
    //如果fork大於零,證明是父進程,即執行下麵的語句
    
    i=11;j=1; sleep(1);  printf("父進程:i=%d,j=%d\n",i,j);
    int sum = i + j;
    printf("父sum = %d\n",sum);

  }
  else
  {
    //如果fork小於零,證明是子進程,執行下麵的語句
    i=12;j=22; sleep(1);  printf("子進程:i=%d,j=%d\n",i,j);
    printf("子sum = %d\n",i+j);

  }
}
    從 fork() 這個函數開始出現後,便創建了子進程,並且子進程和父進程一樣從fork(這個函數一起執行下去,也就是說從fork()開始的下麵所有代碼分別被父 進程和子進程都執行了一次,如果沒有條件判斷語句判別fork()的返回值,將無法分別子父進程,根據fork()的返回值可以令子父進程跳過或執行某條語句

運行結果

 

 

 

 

來源:www.freecplus.net

作者:碼農有道

 

作業:

(1)編寫一個多進程程式,驗證子進程是複製父進程的記憶體變數,還是父子進程共用記憶體變數?

 

複製記憶體變數

 

 

 

2)編寫一個示常式序,由父進程生成10個子進程,在子進程中顯示它是第幾個子進程和子進程本身的進程編號。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
  int i = 0;
  while (i < 10)
  {

    if (fork() > 0) 
    {
      i++;
      continue; //父進程回到while(迴圈),
    }
    else
    {
      printf("子進程第%d個,pid = %d\n", i, getpid());
      break;
    }
  }
  sleep(10);

  return 0;
}

 

運行結果

 

 

 

 

 

 

3)編寫示常式序,由父進程生成子進程,子進程再生成孫進程,共生成第10代進程,在各級子進程中顯示它是第幾代子進程和子進程本身的進程編號。

 

如圖

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
  int i = 0; //全局變數,計數器,計算第幾代子進程
  while (i < 10)
  {

    if (fork()== 0)
    {
      i++;
      continue;
    }
    else
    {
      printf("第%d代子進程,pid = %d\n", i, getpid()); 第 0 代子進程是第一個父進程
    
      break;
    }
  }
  sleep(10);

  return 0;
}

 

運行結果:

子進程是下一個子進程的父進程

 

 

 

4)利用儘可能少的代碼快速fork出更多的進程,試試看能不能把linux系統搞死。

 

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
  int i = 0; //全局變數,計數器,計算第幾代子進程
  while (i < 10)
  {

    if (fork()>0)
    {
      fork();
      
    
      
    }
  }
  printf("pid=%d",getpid());

  return 0;
}

 

 

 

 

 

5)ps -ef |grep book251命令是ps和grep兩個系統命令的組合,各位查一下資料,瞭解一下grep命令的功能,對程式員來,grep是經常用到的命令。

 

 https://blog.csdn.net/weixin_52273136/article/details/110451596

 

 

來源:C語言技術網(www.freecplus.net

作者:碼農有道

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 引言 在學習mysql時,我們經常會使用explain來查看sql查詢的索引等優化手段的使用情況。在使用explain時,我們可以觀察到,explain的輸出有一個很關鍵的列,它就是type屬性,type表示的是掃描方式,代表 MySQL 使用了哪種索引類型,不同的索引類型的查詢效率是不一樣的。 在 ...
  • 一、概述 複合事件處理(簡稱Complex Event Processing:CEP)是一種基於動態環境中事件流的分析技術,事件在這裡通常是有意義的狀態變化,通過分析事件間的關係,利用過濾、關聯、聚合等技術,根據事件間的時序關係和聚合關係制定檢測規則,持續地從事件流中查詢出符合要求的事件序列,最終分 ...
  • 一、引言 過往的工作中,接觸過一些不同的ERP系統。一個系統的數據字典,對於系統推行、運維、二次開發、深度定製,起到非常重要的橋梁作用。因此,記錄一下各個系統生成數據字典的SQL語句,以便於快速查詢。 二、數據字典 2.1、天思經理人ERP 版本:V9.2.8 --天思經理人ERP V9.2.8 U ...
  • zset底層的數據結構為什麼使用調表而不是紅黑樹 前言 Redis中使用到的數據結構以及各個數據對象的底層數據結構在上一篇文章已經寫得非常詳細,這裡不再贅述。 https://www.cnblogs.com/ruigedada/p/16248689.html zset的底層數據結構是壓縮列表和跳錶, ...
  • 一、基礎知識 1、xml:元素、屬性和值。 2、xpath:定址語言,類似Windows目錄的查找。 語法格式: 1)"."表示自己,".."表示父親,"/"表示兒子,"//"表示後代,"name"表示按名字查找,"@name"表示按屬性查找。 2)"集合[條件]" 表示根據條件取集合的子集,條件可 ...
  • 這個問題出現在多表關聯時, 如一張商品表,其中的單位的字元串表示是在單位表中, 但這個單位的id之後進行了刪除,並且不再奏效。 如下: select * from (select pg0.id,pg0.init_size,pg0.goods_id, pg0.goods_move_size,pg0.e ...
  • 今天發現之前學的愛前端的課中JS部分函數等不全,果斷換了一個課——渡一的《Web前端開發JavaScript高薪課堂》接著學習,不過廢話有點多 1、條件語句 語法: 1、單if,條件成立,執行語句體 if (條件){ 語句體; } 2、if else,條件成立,執行if後的語句體,否則執行else的 ...
  • JS 頁面演示背景 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>ivanlee</title> <link rel="shortcut icon" href="ab_favicon.ico"> <styl ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文將以 C# 語言來實現一個簡單的布隆過濾器,為簡化說明,設計得很簡單,僅供學習使用。 感謝@時總百忙之中的指導。 布隆過濾器簡介 布隆過濾器(Bloom filter)是一種特殊的 Hash Table,能夠以較小的存儲空間較快地判斷出數據是否存在。常用於允許一定誤判率的數據過濾及防止緩存 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 「簡單有價值的事情長期堅持做」 這是成功最簡單,但也最難學的秘訣。不經過訓練,人很難意識到時間複利的威力。 仙劍奇俠傳的「十里坡劍神」和金庸群俠傳的「十級野球拳」,就是簡單的事情持之以恆反覆做,最後就有巨大的威力 唐家三少成為網文收入第一,最重要的一步是十四年從未斷日更 這樣的案例很多,一開始可能成 ...
  • 迎面走來了你的面試官,身穿格子衫,挺著啤酒肚,髮際線嚴重後移的中年男子。 手拿泡著枸杞的保溫杯,胳膊夾著MacBook,MacBook上還貼著公司標語:“我愛加班”。 面試開始,直入正題。 面試官: 看你簡歷上面寫著精通MySQL,我先問你事務的特性是什麼? 老生常談,這個還有誰不會背的嗎? 我: ...
  • 基礎知識 python是一門腳本語言,它是解釋執行的。 python使用縮進做為語法,而且python2環境下同一個py文件中不能同時存在tab和空格縮進,否則會出錯,建議在IDE中顯示縮進符。 python在聲明變數時不寫數據類型,可以type(xx)來獲取欄位的類型,然後可以int(),list ...
  • 為什麼要多線程下載 俗話說要以終為始,那麼我們首先要明確多線程下載的目標是什麼,不外乎是為了更快的下載文件。那麼問題來了,多線程下載文件相比於單線程是不是更快? 對於這個問題可以看下圖。 橫坐標是線程數,縱坐標是使用對應線程數下載對應文件時花費的時間,藍橙綠代表下載文件的大小,每個線程下載對應文件2 ...
  • 詳細講解python爬蟲代碼,爬微博搜索結果的博文數據。 爬取欄位: 頁碼、微博id、微博bid、微博作者、發佈時間、微博內容、轉發數、評論數、點贊數。 爬蟲技術: 1、requests 發送請求 2、datetime 時間格式轉換 3、jsonpath 快速解析json數據 4、re 正則表達式提... ...
  • 背景: 一般我們可以用HashMap做本地緩存,但是HashMap功能比較弱,不支持Key過期,不支持數據範圍查找等。故在此實現了一個簡易的本地緩存,取名叫fastmap。 功能: 1.支持數據過期 2.支持等值查找 3.支持範圍查找 4.支持key排序 實現思路: 1.等值查找採用HashMap2 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 本章是系列文章的第八章,用著色演算法進行寄存器的分配過程。 本文中的所有內容來自學習DCC888的學習筆記或者自己理解的整理,如需轉載請註明出處。周榮華@燧原科技 寄存器分配 寄存器分配是為程式處理的值找到存儲位置的問題 這些值可以存放到寄存器,也可以存放在記憶體中 寄存器更快,但數量有限 記憶體很多,但 ...