中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

html怎么添加背景圖片四川整站優(yōu)化關(guān)鍵詞排名

html怎么添加背景圖片,四川整站優(yōu)化關(guān)鍵詞排名,福田網(wǎng)站建設(shè)結(jié)業(yè)論文,做網(wǎng)站的流程視頻文章目錄 實(shí)驗(yàn)內(nèi)容一、進(jìn)程的創(chuàng)建1、編輯源程序2、編輯結(jié)果3、編譯和運(yùn)行程序4、解釋運(yùn)行結(jié)果 二、進(jìn)程共享1、運(yùn)行2、解釋運(yùn)行結(jié)果 三、進(jìn)程終止1、運(yùn)行2、解釋運(yùn)行結(jié)果 四、進(jìn)程同步1、運(yùn)行2、解釋運(yùn)行結(jié)果 五、Linux中子進(jìn)程映像的重新裝入1、運(yùn)行2、解釋運(yùn)行結(jié)果 六、線程1…

文章目錄

  • 實(shí)驗(yàn)內(nèi)容
    • 一、進(jìn)程的創(chuàng)建
      • 1、編輯源程序
      • 2、編輯結(jié)果
      • 3、編譯和運(yùn)行程序
      • 4、解釋運(yùn)行結(jié)果
    • 二、進(jìn)程共享
      • 1、運(yùn)行
      • 2、解釋運(yùn)行結(jié)果
    • 三、進(jìn)程終止
      • 1、運(yùn)行
      • 2、解釋運(yùn)行結(jié)果
    • 四、進(jìn)程同步
      • 1、運(yùn)行
      • 2、解釋運(yùn)行結(jié)果
    • 五、Linux中子進(jìn)程映像的重新裝入
      • 1、運(yùn)行
      • 2、解釋運(yùn)行結(jié)果
    • 六、線程
      • 1、運(yùn)行
      • 2、解釋運(yùn)行結(jié)果
    • 七、共享資源的互斥訪問
      • 1、運(yùn)行
      • 2、解釋運(yùn)行結(jié)果

實(shí)驗(yàn)內(nèi)容

一、進(jìn)程的創(chuàng)建

編寫一段源程序,使用系統(tǒng)調(diào)用fork()創(chuàng)建子進(jìn)程,當(dāng)此程序運(yùn)行時(shí),在系統(tǒng)中有父進(jìn)程和子進(jìn)程在并發(fā)執(zhí)行。觀察屏幕上的顯示結(jié)果,并分析原因(源代碼:forkpid.c)。

1、編輯源程序

在這里插入圖片描述

2、編輯結(jié)果

在這里插入圖片描述

3、編譯和運(yùn)行程序

在這里插入圖片描述

4、解釋運(yùn)行結(jié)果

假設(shè)命令./forkpid創(chuàng)建的進(jìn)程稱為A,則A中的fork()調(diào)用會創(chuàng)建一個(gè)子進(jìn)程,稱為B。

fork()函數(shù)只在父進(jìn)程A中成功被調(diào)用一次,但是在A和B兩個(gè)進(jìn)程中都會有返回值。成功創(chuàng)建子進(jìn)程后,在父進(jìn)程A中,fork的返回值為創(chuàng)建的子進(jìn)程的pid;在子進(jìn)程中,fork的返回值為0。

因此,if(p1==0)后面的代碼塊會在子進(jìn)程中被執(zhí)行,而else后面的代碼塊會在父進(jìn)程中被執(zhí)行。由上述運(yùn)行結(jié)果可知,進(jìn)程的創(chuàng)建關(guān)系如下。

pid: 389733 --> 390075(A) --> 390076(B)

那么還有一個(gè)問題,上述運(yùn)行結(jié)果中的My parent is 1,豈不是說B進(jìn)程的父進(jìn)程pid是1?這不是矛盾了嗎?根據(jù)我所查閱的資料,這是因?yàn)楦高M(jìn)程A比子進(jìn)程B先結(jié)束,B中查找自己的父進(jìn)程時(shí),父進(jìn)程A已經(jīng)不在了,會使用pid為1的進(jìn)程代替。在Linux中,pid號為1的進(jìn)程是所有進(jìn)程的祖先進(jìn)程。

參考

  1. https://blog.csdn.net/lein_wang/article/details/81946108 - 為什么父進(jìn)程id是1
  2. https://www.cnblogs.com/alantu2018/p/8526970.html - linux的 0號進(jìn)程 和 1 號進(jìn)程

二、進(jìn)程共享

父進(jìn)程創(chuàng)建子進(jìn)程后,父子進(jìn)程各自分支中的程序各自私有,其余部分,包括創(chuàng)建前和分支結(jié)束后的程序段,均為父子進(jìn)程共享。(源代碼:forkshare_1.c)

1、運(yùn)行

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

2、解釋運(yùn)行結(jié)果

根據(jù)運(yùn)行結(jié)果我們很容易看出,進(jìn)程調(diào)度順序和上一節(jié)中一樣,是先調(diào)度父進(jìn)程再調(diào)度字進(jìn)程。其中前三個(gè)字母xay是父進(jìn)程的輸出,后面三個(gè)字母xby則是子進(jìn)程的輸出。

可令人困惑不解的是,子進(jìn)程不也應(yīng)該從fork()返回的地方開始運(yùn)行嗎?那為什么'x'會被輸出兩次?我一時(shí)間有些蒙圈。

在查找資料后,我嘗試了另一個(gè)示例,其中僅僅是將putchar('x')換成了printf("x\n"),而最主要的區(qū)別就是多了一個(gè)\n。下面是代碼及其運(yùn)行結(jié)果。

在這里插入圖片描述
在這里插入圖片描述

子進(jìn)程會從fork()返回的地方開始執(zhí)行,沒有錯(cuò)。問題出在stdout緩沖區(qū)的機(jī)制上,在輸出xayxby的示例中,運(yùn)行putchar('x')語句并沒有直接將x寫到屏幕上,而僅僅是將x放到了緩沖里。隨后運(yùn)行fork()創(chuàng)建子進(jìn)程,會將父進(jìn)程的stdout緩沖區(qū)也復(fù)制一份,而復(fù)制的緩沖區(qū)中就包含了剛剛放入的x。這便是兩個(gè)x從何而來。

而如果打印的內(nèi)容中包含了\n,就會馬上將內(nèi)容寫到屏幕上并刷新緩沖區(qū),這便是為什么第二個(gè)示例中x只有一個(gè)。

參考:

  1. https://blog.csdn.net/koches/article/details/7787468 - linux中fork–子進(jìn)程是從哪里開始運(yùn)行

三、進(jìn)程終止

如果子進(jìn)程在其分支結(jié)束處使用了進(jìn)程終止exit()系統(tǒng)調(diào)用而終止執(zhí)行,則不會再執(zhí)行分支結(jié)束后的程序段。(源代碼:forkshare_2.c)

1、運(yùn)行

在這里插入圖片描述
在這里插入圖片描述

2、解釋運(yùn)行結(jié)果

子進(jìn)程因?yàn)樵诜种е休敵?code>b后就exit()結(jié)束進(jìn)程了,因此子進(jìn)程不會輸出后面的y,其它與上一節(jié)情況相同,不作多解釋。


四、進(jìn)程同步

當(dāng)父進(jìn)程有許多任務(wù)要做時(shí),往往會針對每一個(gè)任務(wù)創(chuàng)建一個(gè)子進(jìn)程去完成,然后再等待每一個(gè)子進(jìn)程的終止。其同步關(guān)系是父進(jìn)程等待子進(jìn)程 (源代碼:wait.c)。

實(shí)現(xiàn)的方法是:1)子進(jìn)程終止時(shí)執(zhí)行exit()向父進(jìn)程發(fā)終止信號,2)父進(jìn)程使用wait()等待子進(jìn)程的終止。

1、運(yùn)行

在這里插入圖片描述
在這里插入圖片描述

2、解釋運(yùn)行結(jié)果

前面三個(gè)程序都是父進(jìn)程輸出的 va在前而子進(jìn)程輸出的b在后,這次ba換子進(jìn)程的輸出在前了。

父進(jìn)程中掉用wait(0)函數(shù)會立即阻塞自己,并等待子進(jìn)程的退出。注意阻塞和空循環(huán)等待是有區(qū)別的,進(jìn)程阻塞自己后會交出cpu的控制權(quán)。

不過,wait(0)exit(0)中都有一個(gè)0,這個(gè)0是什么意思呢?其實(shí)這兩個(gè)零并不是同一個(gè)東西,wait的函數(shù)頭原型是int wait(int *status),參數(shù)是一個(gè)int類型的指針,wait(0)其實(shí)相當(dāng)于wait(NULL),這個(gè)參數(shù)為NULL表示我們不關(guān)心子進(jìn)程是如何退出的,只要退出就行。而如果你寫成wait(1),那么編譯時(shí)候就會報(bào)錯(cuò)了,因?yàn)轭愋筒黄ヅ洹?/p>

exit(0)的參數(shù)是退出碼,你完全可以使用任性地使用exit(123)退出子進(jìn)程,并在父進(jìn)程中仍然以wait(0)接收子進(jìn)程的終止信號。

參考:

  1. https://zhuanlan.zhihu.com/p/549981187 - 入門篇:進(jìn)程等待函數(shù)wait詳解
  2. https://blog.csdn.net/qustdjx/article/details/7704323 - wait()以及wait(&status)\ waitpid()
  3. https://zhuanlan.zhihu.com/p/647776823 - Linux Shell 中的各種退出碼
  4. https://www.cnblogs.com/shikamaru/p/5359731.html - exit(0)、exit(1)、和return

五、Linux中子進(jìn)程映像的重新裝入

創(chuàng)建一個(gè)子進(jìn)程,并給它加載程序,其功能是顯示“I am a child”。設(shè)被加載的程序路徑名為./child。分析:由于子進(jìn)程需要加載的程序比較簡單,不帶參數(shù),所以可以使用execl()實(shí)現(xiàn)加載。

1、運(yùn)行

./child_parent.c:

在這里插入圖片描述

./child.c

在這里插入圖片描述

在這里插入圖片描述

2、解釋運(yùn)行結(jié)果

我在./child_parent.c文件的execl()語句后加了一個(gè)printf()語句,這樣也行能夠更好地體現(xiàn)execl的運(yùn)行機(jī)制。

上述源代碼中共有兩個(gè)printf語句,但最終只有./child.c中的printf語句產(chǎn)生了輸出。這是因?yàn)?#xff0c;execl加載進(jìn)程時(shí)并不會新建一個(gè)進(jìn)程,而是使用傳入路徑中的程序覆蓋當(dāng)前進(jìn)程,并從新進(jìn)程的main函數(shù)開始執(zhí)行。覆蓋后,使用fork()創(chuàng)建的那個(gè)程序,當(dāng)然也包括其中的printf("I am child A\n"),已經(jīng)不存在了。

使用execl,子進(jìn)程可以更好地干自己的活,而不只是作為父進(jìn)程的拷貝。

參考

  1. https://blog.csdn.net/bao_bei/article/details/48287945 - Linux下execl函數(shù)學(xué)習(xí)_linux的execl函數(shù)

六、線程

Linux 系統(tǒng)下的多線程遵循 POSIX 線程接口,稱為 pthread。編寫 Linux 下的多線程程式,需要使用頭文檔 pthread.h,連接時(shí)需要使用庫 libpthread。順便說一下,Linux 下pthread 的實(shí)現(xiàn)是通過系統(tǒng)調(diào)用 clone()來實(shí)現(xiàn)的。clone()是 Linux 所特有的系統(tǒng)調(diào)用,他的使用方式類似 fork,關(guān)于 clone()的周詳情況,有興趣的讀者能夠去查看有關(guān)文檔說明。下面我們展示一個(gè)最簡單的多線程程序 pthread_create.c。

1、運(yùn)行

在這里插入圖片描述

在這里插入圖片描述

2、解釋運(yùn)行結(jié)果

// 線程創(chuàng)建函數(shù)的函數(shù)頭
int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*strat_routine)(void *), void *arg)

返回值(int):創(chuàng)建成功時(shí)返回0,失敗時(shí)返回錯(cuò)誤碼。

參數(shù):

  • thread:前面先創(chuàng)建了空的線程標(biāo)識符pthread_t id1,這里傳入&id1告訴函數(shù)要將新建線程的標(biāo)識符放到哪里??梢詫Ρ?code>scanf("%d", &x)的用法。
  • attr:線程的屬性,傳入NULL表示默認(rèn)。
  • start_routine:線程要執(zhí)行的函數(shù)的指針,上述示例代碼中實(shí)參前的(void*)大概是強(qiáng)制類型轉(zhuǎn)換為指針的意思。函數(shù)頭中那一串void *(*strat_routine)(void *)你可能看著有點(diǎn)暈,感覺自己的C語言功底不太夠用了,抱歉我也是。
  • arg:線程要執(zhí)行的函數(shù)所需要的參數(shù),傳入NULL意思是不需要參數(shù)。

我在main函數(shù)return前添加了一個(gè)printf語句。

pthread_join的作用是讓主線程進(jìn)入阻塞態(tài),等待子線程運(yùn)行結(jié)束后,主線程再接著運(yùn)行。否則,從子線程創(chuàng)建時(shí)開始,主線程與兩個(gè)子線程就開始并發(fā)執(zhí)行,當(dāng)主線程很快運(yùn)行結(jié)束并return后,整個(gè)進(jìn)程也會結(jié)束,即子線程跟著結(jié)束,都來不及在屏幕上打印信息。

可以看到輸出中交替打印兩個(gè)字符串各四次后,最后打印出來的是This is main thread.。

參考

  1. https://blog.csdn.net/sevens_0804/article/details/102823184 - Linux多線程操作pthread_t
  2. https://www.jb51.net/article/176510.htm - 簡單了解C語言中主線程退出對子線程的影響

七、共享資源的互斥訪問

創(chuàng)建兩個(gè)線程來實(shí)現(xiàn)對一個(gè)數(shù)的遞加 pthread_example.c

1、運(yùn)行

例程1

代碼太長,截圖不便,我直接貼文本吧。

#include<pthread.h>
#include<stdlib.h>
#include<stdio.h>
#include<sys/time.h>
#include<string.h>
#include<unistd.h>
#define MAX 10pthread_t thread[2];
pthread_mutex_t mut;
int number=0;
int i;void thread1(){printf("thread1: I'm thread 1\n");for(i=0;i<MAX;i++){printf("thread1: number=%d\n",number);pthread_mutex_lock(&mut);number++;pthread_mutex_unlock(&mut);sleep(2);}pthread_exit(NULL);
}
void thread2(){printf("thread2: I'm thread 2\n");for(i=0;i<MAX;i++){printf("thread2: number=%d\n",number);pthread_mutex_lock(&mut);number++;pthread_mutex_unlock(&mut);sleep(3);}pthread_exit(NULL);
}
void thread_create(){int temp;memset(&thread,0,sizeof(thread));if( (temp=pthread_create(&thread[0],NULL,(void*)thread1,NULL)) != 0){printf("create thread1 failed!\n");}else{printf("create thread1 success!\n");}if( (temp=pthread_create(&thread[1],NULL,(void*)thread2,NULL)) != 0){printf("create thread2 failed!\n");}else{printf("create thread2 success!\n");}
}
void thread_wait(){if(thread[0]!=0){pthread_join(thread[0],NULL);printf("thread1 end!\n");}if(thread[1]!=0){pthread_join(thread[1],NULL);printf("thread2 end!\n");}						        
}
int main(){pthread_mutex_init(&mut,NULL);printf("I am main, I am creating thread!\n");thread_create();printf("I am main, I am waiting thread end!\n");thread_wait();return 0;
}

在這里插入圖片描述

2、解釋運(yùn)行結(jié)果

進(jìn)程是資源分配的基本單位,線程是調(diào)度的基本單位。上述代碼中,int numberint i都是被兩個(gè)線程所共享的變量。利用mutex可以實(shí)現(xiàn)對共享資源的互斥訪問,這個(gè)比較容易理解,但是上面的運(yùn)行結(jié)果中,可能有些令人疑惑的地方。

1、為什么會打印兩次"number=0",這正常嗎?

是正常的,比如在如下圖所示的執(zhí)行順序(但不唯一)中,就會出現(xiàn)打印兩次"number=0"然后打印"number=2"的情況。注意sleep()會直接讓當(dāng)前進(jìn)程阻塞,因此下圖中在sleep處都是拐點(diǎn)。

在這里插入圖片描述

2、為什么thread1連續(xù)輸出了兩個(gè)數(shù)"number=6"和"number=7"?

對進(jìn)程的同步與互斥有些模糊時(shí),容易產(chǎn)生這樣的疑問。運(yùn)行結(jié)果中,大部分輸出都是thread1和thread2交替的,只有6和7這里是同一個(gè)線程連續(xù)輸出兩次,以至于覺得本應(yīng)該交替輸出、而連續(xù)輸出是異常的。

其實(shí)不是,上述thread1的代碼中是sleep(2),而thread2的代碼中是sleep(3)。如果你將thread1中的sleep(2)修改成sleep(1),可以觀察到大部分時(shí)候都是thread1在連續(xù)輸出??傊?#xff0c;代碼中只是使用mutex實(shí)現(xiàn)了對共享資源的互斥訪問而已,并沒有實(shí)現(xiàn)同步。

3、驗(yàn)證lock與unlock的作用。

到這里,我只知道m(xù)utex可以實(shí)現(xiàn)對共享資源(全局變量number)的互斥訪問,程序也確實(shí)看起來正常運(yùn)行。不過,它只循環(huán)了10次呢。而且不知道你有沒有發(fā)現(xiàn)一個(gè)問題,另一個(gè)全局變量i,不也同樣是thread1和thread2兩個(gè)線程的共享資源嗎?

讓我們將總循環(huán)次數(shù)提到10萬吧:#define MAX=100000,同時(shí)將阻塞時(shí)間縮到sleep(0.001)讓它運(yùn)行得快一點(diǎn)。然后重新編譯并運(yùn)行一下我們的代碼:

例程2

在這里插入圖片描述

看!最后結(jié)果是number=100018,而并不是我們所設(shè)置的100000,那么很可能就是由于對于共享變量 i 的訪問發(fā)生了沖突。我將例程2運(yùn)行了5次,記錄每次最后的number值如下:

100018 100017 100011 100024 100009

為了驗(yàn)證確實(shí)是變量 i 導(dǎo)致的問題,而不是其它的什么原因——比如上帝在你的計(jì)算機(jī)里邊擲骰子,我們不妨給 i 也加上互斥。

例程3

我新增了一個(gè)新的用于互斥的變量mut_i,并在兩個(gè)線程函數(shù)的循環(huán)中都改用lockunlock來保護(hù)記錄循環(huán)迭代的i++語句。

在這里插入圖片描述
在這里插入圖片描述

我同樣將這個(gè)修改后的例程3運(yùn)行了5次,其中有四次是正確的結(jié)果number=100000??珊苓z憾,我也不知道在第一次運(yùn)行中為什么會出現(xiàn)連續(xù)兩個(gè)number=99999,不過我覺得這不一定是資源互斥中所導(dǎo)致的問題。

總之,凡有賦值的操作在多線程環(huán)境都要加鎖,不論是上述的number++,還是i++。因?yàn)?#xff0c;它們都不是原子操作,從機(jī)器指令的層面來看,一個(gè)高級語言中的i++包含多個(gè)步驟,而一條語句還沒執(zhí)行完,可能就已經(jīng)發(fā)生中斷,轉(zhuǎn)而去執(zhí)行另一個(gè)線程了。

4、在例程2和例程3的執(zhí)行結(jié)果中,每次最終的number值都是偏大,為什么不會偏小呢?

例程4

下面我解除了對于變量 number 的互斥保護(hù),而保持對 i 的互斥保護(hù)。

在這里插入圖片描述

在這里插入圖片描述

可以看到我連續(xù)運(yùn)行五次結(jié)果中,number 每次都是比10萬要偏小。這個(gè)具體的細(xì)節(jié),其實(shí)回憶一下以前數(shù)據(jù)庫并發(fā)控制中丟失修改導(dǎo)致的數(shù)據(jù)不一致問題,就明白了,情況如下圖所示。而當(dāng) i 偏小的時(shí)候,i 的遞增次數(shù)就小于實(shí)際迭代次數(shù),于是導(dǎo)致了 number 的結(jié)果偏大。

在這里插入圖片描述

參考

  1. https://blog.csdn.net/JMW1407/article/details/108318960 - int i =1 是原子操作嗎?i++是原子操作嗎?

http://m.risenshineclean.com/news/61900.html

相關(guān)文章:

  • 網(wǎng)站開發(fā)在哪里接活網(wǎng)站查詢工具
  • 做論壇網(wǎng)站需要什么備案廈門seo代運(yùn)營
  • 做一個(gè)營銷型網(wǎng)站手機(jī)網(wǎng)站建設(shè)公司
  • 吉林省建設(shè)局網(wǎng)站軟文推廣什么意思
  • 衡水哪有做網(wǎng)站的網(wǎng)上宣傳廣告怎么做
  • 南京自助建站網(wǎng)站社群營銷策略有哪些
  • 怎么做外貿(mào)推廣網(wǎng)站搜索關(guān)鍵詞優(yōu)化
  • 怎樣做能直接上傳微信的視頻網(wǎng)站莆田網(wǎng)站建設(shè)優(yōu)化
  • 做社交網(wǎng)站開發(fā)怎么建網(wǎng)站免費(fèi)的
  • 網(wǎng)站開發(fā)代做外貿(mào)網(wǎng)站制作推廣
  • 沒網(wǎng)站域名可以做備案嗎百度熱度
  • 塘沽網(wǎng)站建設(shè)網(wǎng)站建設(shè)方案內(nèi)容
  • 域名怎么解析到網(wǎng)站網(wǎng)絡(luò)營銷策略的制定
  • 新民正規(guī)網(wǎng)站建設(shè)價(jià)格咨詢高級seo是什么職位
  • 高端網(wǎng)站設(shè)計(jì)建站找個(gè)免費(fèi)網(wǎng)站這么難嗎
  • 青海省建設(shè)網(wǎng)站多少錢今日頭條(官方版本)
  • b2b電子商務(wù)平臺選擇有哪些seo網(wǎng)站平臺
  • 格爾木市住房和城鄉(xiāng)建設(shè)局網(wǎng)站做專業(yè)搜索引擎優(yōu)化
  • 網(wǎng)站外鏈帶nofollow是什么意思網(wǎng)站快速優(yōu)化排名官網(wǎng)
  • 網(wǎng)絡(luò)技術(shù)與網(wǎng)站建設(shè)seo網(wǎng)站優(yōu)化課程
  • 東南網(wǎng)架公司哈爾濱seo和網(wǎng)絡(luò)推廣
  • 貴港網(wǎng)站設(shè)計(jì)免費(fèi)發(fā)布網(wǎng)站seo外鏈
  • 外貿(mào)添加外鏈網(wǎng)站建站網(wǎng)站
  • 有ip怎么用自己的主機(jī)做網(wǎng)站灰色項(xiàng)目推廣渠道
  • 引用網(wǎng)站的內(nèi)容如何做注釋排行榜軟件
  • 寧波市住房與城鄉(xiāng)建設(shè)部網(wǎng)站百度推廣一天燒幾千
  • 專業(yè)攝影網(wǎng)站杭州網(wǎng)站優(yōu)化服務(wù)
  • 高端服裝產(chǎn)品網(wǎng)站建設(shè)seo建站平臺哪家好
  • 網(wǎng)站策劃步驟網(wǎng)站交易
  • 個(gè)人網(wǎng)站設(shè)計(jì)成首頁網(wǎng)絡(luò)營銷的實(shí)現(xiàn)方式