日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux进程线程

發布時間:2025/4/16 linux 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux进程线程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.進程

進程的引入是因為為了滿足多用戶多任務的操作的需要,對于每個任務需要分別分配一個進程進行控制。對于每個進程很顯然要標識它所擁有的資源。所以這里就引入了PCB(process control block)這個概念,對于每個PCB會有保存的各個資源變量。當你有了PCB的概念后,緊接著就是面臨三個問題就是。

  1.如何創建一個進程

  2. 在新建的一個進程里如何執行自己的程序

  3. 創建的函數如何回收資源

這樣就引出了三個函數,fork(),execve()以及wait()函數。fork()函數是創建新進程的函數,通過一次調用兩次返回,來實現對父進程以及子進程的判斷。execve是在新創建的進程中如何load用戶想執行程序的函數。execve函數分為以下幾個函數。

1 #include <unistd.h> 2 3 int execl(const char *path, const char *arg, ...); 4 int execlp(const char *file, const char *arg, ...); 5 int execle(const char *path, const char *arg, ..., char *const envp[]); 6 int execv(const char *path, char *const argv[]); 7 int execvp(const char *file, char *const argv[]); 8 int execve(const char *path, char *const argv[], char *const envp[]);

其中函數中如果缺少字母p(path) l(list) e(enviroment)則在參數中必須給出。其中execve是系統調用,其它的函數實際上還是調用它來完成功能。?

wait()函數是清理子進程的函數。如果一個進程結束了,父進程沒有調用wait()對其清理的話,那么這個進程叫做僵尸進程。而如果父進程結束了,而子進程未結束,那么這個進程的父進程改為init進程,init進程會自動清理子進程。處理僵尸進程的一個方法是利用信號來處理,因為子進程結束時會給父進程發送SIGCHILD信號,這時父進程把該信號的默認處理函數改為清理函數即可。

1 #include <sys/types.h> 2 #include <sys/wait.h> 3 4 pid_t wait(int *status); 5 pid_t waitpid(pid_t pid, int *status, int options);

對于wait以及waitpid主要有兩個方面的區別

1. waitpid可以通過pid指定要清理的進程

2.其中OPTIONS指定WNOHANG可以使得waitpid不阻塞

另一個話題就是進程間的通信問題。

linux進程間的通信方法總結如下

  • 通過fork函數把打開文件的描述符傳遞給子進程
  • 通過wait得到子進程的終結信息
  • 通過加鎖的方式,實現幾個進行共享讀寫某個文件
  • 進行間通過信號通信,SIGUSR1和SIGUSR2實現用戶定義功能
  • 利用pipe進行通信
  • FIFO文件進行通信
  • mmap,幾個進程映射到同一內存區(其中有個MAP_SHARED參數)
  • SYS IPC 消息隊列,信號量(很少用)
  • UNIX Domain Socket,常用

其中利用pipe函數是在內核中開辟一個緩沖區進行數據的傳送,但是如果通信的進程間沒有從公共的父進程哪里繼承文件描述符,那么要考慮使用FIFO/Socket文件進行通信,因為文件的位置是一定的,FIFO以及Socket其實不是實際存在的文件,只是用來表示內核通道的文件。

2.線程

因為進程在創建以及切換的過程中消耗的資源很大,所以就引入了線程的手段。線程其實也被稱作輕量集的進程。所以這里我們也可以利用學習進程的三個方面的問題來學習線程。

  1.如何創建線程

  2.如何在線程中加載要運行的函數。

  3.如何回收/結束創建的線程

這里線程的創建以及加載運行所要的函數都是通過pthread_create函數來實現的。

1 #include <pthread.h> 2 3 int pthread_create(pthread_t *restrict thread, 4 const pthread_attr_t *restrict attr, 5 void *(*start_routine)(void*), void *restrict arg);

其中thread是線程的pid,start_routine是線程要執行的函數指針, arg是其參數。attr則是指的線程的屬性。

結束某個線程而又不結束整個進程,可以有三個方法。

  1. 從線程函數return,?

  2. pthread_cancel終止同一個進程的另一個線程

  3. pthread_exit終止自己

與waitpid一樣我們有時也需要獲取結束線程是否成功,這樣就引入了pthread_join()函數

1 #include <pthread.h> 2 3 int pthread_join(pthread_t thread, void **value_ptr);

其主要作用是掛起等待線程的結束,并通過vaule_ptr返回其值。

由于線程中很多資源都是進程中共享的,當頻繁的對進程進行讀寫操作的時候,很容易產生訪問共享數據沖突的情形,所以需要引入鎖來解決這個問題。

1 #include <pthread.h> 2 3 int pthread_mutex_destroy(pthread_mutex_t *mutex); 4 int pthread_mutex_init(pthread_mutex_t *restrict mutex, 5 const pthread_mutexattr_t *restrict attr); 6 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 7 8 int pthread_mutex_lock(pthread_mutex_t *mutex); 9 int pthread_mutex_trylock(pthread_mutex_t *mutex); 10 int pthread_mutex_unlock(pthread_mutex_t *mutex);

其中lock以及trylock的區別是一個會阻塞,一個不會阻塞。鎖所帶來的一個問題就是死鎖問題,死鎖就是多個線程加鎖與解鎖的順序不對導致其全部阻塞。這里為了防止死鎖。首先要盡量避免多次同時獲取多個鎖。實在無法避免則所有的線程按照順序獲取與釋放,如獲取鎖1,鎖2,鎖3,釋放鎖1,鎖2,鎖3.如果這個都無法保證那么就使用trylock來代替lock。

另外線程間同步機制還有其它兩種方式分別是條件變量以及信號量。

條件變量的同步主要是為了滿足這樣的一個條件,那就是當線程A阻塞時,需要線程B在某個時間喚醒它。也就是說通過線程B給其發信號。而信號量則主要是可是實現多個線程可以同時進行的鎖?;コ怄i可以看作其一種特殊的情形。信號量也可以使用在進程間同步中。

線程間通信方式如下

  • 鎖機制
  • 信號量機制
  • 信號機制?
  • 全局變量
  • 參數傳遞

3. 線程與進程的比較

  • 地址空間:進程內的一個執行單元;進程至少有一個線程;它們共享進程的地址空間;而進程有自己獨立的地址空間;
  • 資源擁有:進程是資源分配和擁有的單位,同一個進程內的線程共享進程的資源
  • 線程是處理器調度的基本單位,但進程不是.
  • 二者均可并發執行.

轉載于:https://www.cnblogs.com/qtalker/p/4582059.html

總結

以上是生活随笔為你收集整理的Linux进程线程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。