當前位置:首頁 » 操作系統 » linux多線程多進程

linux多線程多進程

發布時間: 2022-09-18 08:53:13

linux多進程和線程同步的幾種方式

Linux 線程同步的三種方法
線程的最大特點是資源的共享性,但資源共享中的同步問題是多線程編程的難點。linux下提供了多種方式來處理線程同步,最常用的是互斥鎖、條件變數和信號量。
一、互斥鎖(mutex)
通過鎖機制實現線程間的同步。
初始化鎖。在Linux下,線程的互斥量數據類型是pthread_mutex_t。在使用前,要對它進行初始化。
靜態分配:pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
動態分配:int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr);
加鎖。對共享資源的訪問,要對互斥量進行加鎖,如果互斥量已經上了鎖,調用線程會阻塞,直到互斥量被解鎖。
int pthread_mutex_lock(pthread_mutex *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
解鎖。在完成了對共享資源的訪問後,要對互斥量進行解鎖。
int pthread_mutex_unlock(pthread_mutex_t *mutex);
銷毀鎖。鎖在是使用完成後,需要進行銷毀以釋放資源。
int pthread_mutex_destroy(pthread_mutex *mutex);
[csharp] view plain
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <pthread.h>
#include "iostream"
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int tmp;
void* thread(void *arg)
{
cout << "thread id is " << pthread_self() << endl;
pthread_mutex_lock(&mutex);
tmp = 12;
cout << "Now a is " << tmp << endl;
pthread_mutex_unlock(&mutex);
return NULL;
}
int main()
{
pthread_t id;
cout << "main thread id is " << pthread_self() << endl;
tmp = 3;
cout << "In main func tmp = " << tmp << endl;
if (!pthread_create(&id, NULL, thread, NULL))
{
cout << "Create thread success!" << endl;
}
else
{
cout << "Create thread failed!" << endl;
}
pthread_join(id, NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
//編譯:g++ -o thread testthread.cpp -lpthread
二、條件變數(cond)
互斥鎖不同,條件變數是用來等待而不是用來上鎖的。條件變數用來自動阻塞一個線程,直到某特殊情況發生為止。通常條件變數和互斥鎖同時使用。條件變數分為兩部分: 條件和變數。條件本身是由互斥量保護的。線程在改變條件狀態前先要鎖住互斥量。條件變數使我們可以睡眠等待某種條件出現。條件變數是利用線程間共享的全局變數進行同步的一種機制,主要包括兩個動作:一個線程等待"條件變數的條件成立"而掛起;另一個線程使"條件成立"(給出條件成立信號)。條件的檢測是在互斥鎖的保護下進行的。如果一個條件為假,一個線程自動阻塞,並釋放等待狀態改變的互斥鎖。如果另一個線程改變了條件,它發信號給關聯的條件變數,喚醒一個或多個等待它的線程,重新獲得互斥鎖,重新評價條件。如果兩進程共享可讀寫的內存,條件變數可以被用來實現這兩進程間的線程同步。
初始化條件變數。
靜態態初始化,pthread_cond_t cond = PTHREAD_COND_INITIALIER;
動態初始化,int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
等待條件成立。釋放鎖,同時阻塞等待條件變數為真才行。timewait()設置等待時間,仍未signal,返回ETIMEOUT(加鎖保證只有一個線程wait)
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,const timespec *abstime);
激活條件變數。pthread_cond_signal,pthread_cond_broadcast(激活所有等待線程)
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond); //解除所有線程的阻塞
清除條件變數。無線程等待,否則返回EBUSY
int pthread_cond_destroy(pthread_cond_t *cond);
[cpp] view plain
#include <stdio.h>
#include <pthread.h>
#include "stdlib.h"
#include "unistd.h"
pthread_mutex_t mutex;
pthread_cond_t cond;
void hander(void *arg)
{
free(arg);
(void)pthread_mutex_unlock(&mutex);
}
void *thread1(void *arg)
{
pthread_cleanup_push(hander, &mutex);
while(1)
{
printf("thread1 is running\n");
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
printf("thread1 applied the condition\n");
pthread_mutex_unlock(&mutex);
sleep(4);
}
pthread_cleanup_pop(0);
}
void *thread2(void *arg)
{
while(1)
{
printf("thread2 is running\n");
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
printf("thread2 applied the condition\n");
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
int main()
{
pthread_t thid1,thid2;
printf("condition variable study!\n");
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_create(&thid1, NULL, thread1, NULL);
pthread_create(&thid2, NULL, thread2, NULL);
sleep(1);
do
{
pthread_cond_signal(&cond);
}while(1);
sleep(20);
pthread_exit(0);
return 0;
}
[cpp] view plain
#include <pthread.h>
#include <unistd.h>
#include "stdio.h"
#include "stdlib.h"
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
struct node
{
int n_number;
struct node *n_next;
}*head = NULL;

static void cleanup_handler(void *arg)
{
printf("Cleanup handler of second thread./n");
free(arg);
(void)pthread_mutex_unlock(&mtx);
}
static void *thread_func(void *arg)
{
struct node *p = NULL;
pthread_cleanup_push(cleanup_handler, p);
while (1)
{
//這個mutex主要是用來保證pthread_cond_wait的並發性
pthread_mutex_lock(&mtx);
while (head == NULL)
{
//這個while要特別說明一下,單個pthread_cond_wait功能很完善,為何
//這里要有一個while (head == NULL)呢?因為pthread_cond_wait里的線
//程可能會被意外喚醒,如果這個時候head != NULL,則不是我們想要的情況。
//這個時候,應該讓線程繼續進入pthread_cond_wait
// pthread_cond_wait會先解除之前的pthread_mutex_lock鎖定的mtx,
//然後阻塞在等待對列里休眠,直到再次被喚醒(大多數情況下是等待的條件成立
//而被喚醒,喚醒後,該進程會先鎖定先pthread_mutex_lock(&mtx);,再讀取資源
//用這個流程是比較清楚的
pthread_cond_wait(&cond, &mtx);
p = head;
head = head->n_next;
printf("Got %d from front of queue/n", p->n_number);
free(p);
}
pthread_mutex_unlock(&mtx); //臨界區數據操作完畢,釋放互斥鎖
}
pthread_cleanup_pop(0);
return 0;
}
int main(void)
{
pthread_t tid;
int i;
struct node *p;
//子線程會一直等待資源,類似生產者和消費者,但是這里的消費者可以是多個消費者,而
//不僅僅支持普通的單個消費者,這個模型雖然簡單,但是很強大
pthread_create(&tid, NULL, thread_func, NULL);
sleep(1);
for (i = 0; i < 10; i++)
{
p = (struct node*)malloc(sizeof(struct node));
p->n_number = i;
pthread_mutex_lock(&mtx); //需要操作head這個臨界資源,先加鎖,
p->n_next = head;
head = p;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mtx); //解鎖
sleep(1);
}
printf("thread 1 wanna end the line.So cancel thread 2./n");
//關於pthread_cancel,有一點額外的說明,它是從外部終止子線程,子線程會在最近的取消點,退出
//線程,而在我們的代碼里,最近的取消點肯定就是pthread_cond_wait()了。
pthread_cancel(tid);
pthread_join(tid, NULL);
printf("All done -- exiting/n");
return 0;
}
三、信號量(sem)
如同進程一樣,線程也可以通過信號量來實現通信,雖然是輕量級的。信號量函數的名字都以"sem_"打頭。線程使用的基本信號量函數有四個。
信號量初始化。
int sem_init (sem_t *sem , int pshared, unsigned int value);
這是對由sem指定的信號量進行初始化,設置好它的共享選項(linux 只支持為0,即表示它是當前進程的局部信號量),然後給它一個初始值VALUE。
等待信號量。給信號量減1,然後等待直到信號量的值大於0。
int sem_wait(sem_t *sem);
釋放信號量。信號量值加1。並通知其他等待線程。
int sem_post(sem_t *sem);
銷毀信號量。我們用完信號量後都它進行清理。歸還佔有的一切資源。
int sem_destroy(sem_t *sem);
[cpp] view plain
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>
#define return_if_fail(p) if((p) == 0){printf ("[%s]:func error!/n", __func__);return;}
typedef struct _PrivInfo
{
sem_t s1;
sem_t s2;
time_t end_time;
}PrivInfo;

static void info_init (PrivInfo* thiz);
static void info_destroy (PrivInfo* thiz);
static void* pthread_func_1 (PrivInfo* thiz);
static void* pthread_func_2 (PrivInfo* thiz);

int main (int argc, char** argv)
{
pthread_t pt_1 = 0;
pthread_t pt_2 = 0;
int ret = 0;
PrivInfo* thiz = NULL;
thiz = (PrivInfo* )malloc (sizeof (PrivInfo));
if (thiz == NULL)
{
printf ("[%s]: Failed to malloc priv./n");
return -1;
}
info_init (thiz);
ret = pthread_create (&pt_1, NULL, (void*)pthread_func_1, thiz);
if (ret != 0)
{
perror ("pthread_1_create:");
}
ret = pthread_create (&pt_2, NULL, (void*)pthread_func_2, thiz);
if (ret != 0)
{
perror ("pthread_2_create:");
}
pthread_join (pt_1, NULL);
pthread_join (pt_2, NULL);
info_destroy (thiz);
return 0;
}
static void info_init (PrivInfo* thiz)
{
return_if_fail (thiz != NULL);
thiz->end_time = time(NULL) + 10;
sem_init (&thiz->s1, 0, 1);
sem_init (&thiz->s2, 0, 0);
return;
}
static void info_destroy (PrivInfo* thiz)
{
return_if_fail (thiz != NULL);
sem_destroy (&thiz->s1);
sem_destroy (&thiz->s2);
free (thiz);
thiz = NULL;
return;
}
static void* pthread_func_1 (PrivInfo* thiz)
{
return_if_fail(thiz != NULL);
while (time(NULL) < thiz->end_time)
{
sem_wait (&thiz->s2);
printf ("pthread1: pthread1 get the lock./n");
sem_post (&thiz->s1);
printf ("pthread1: pthread1 unlock/n");
sleep (1);
}
return;
}
static void* pthread_func_2 (PrivInfo* thiz)
{
return_if_fail (thiz != NULL);
while (time (NULL) < thiz->end_time)
{
sem_wait (&thiz->s1);
printf ("pthread2: pthread2 get the unlock./n");
sem_post (&thiz->s2);
printf ("pthread2: pthread2 unlock./n");
sleep (1);
}
return;
}

② Linux進程與線程的區別和聯系

進程中可包含多個線程,最少1個,進程可控制進程內線程的運行暫停及結束,線程可共享進程全局變數,進程與進程是單獨個體,相互不能直接訪問各自線程及全局變數

③ Linux中進程和線程的對比與區別

線程和進程是另一對有意義的概念,主要區別和聯系如下:

  • 進程是操作系統進行資源分配的基本單位,擁有完整的進程空間。進行系統資源分配的時候,除了CPU資源之外,不會給線程分配獨立的資源,線程所需要的資源需要共享。

  • 線程是進程的一部分,如果沒有進行顯示的線程分配,可以認為進程是單線程的;如果進程中建立了線程,則可認為系統是多線程的。

  • 多線程和多進程是兩種不同的概念。多線程與多進程有不同的資源共享方式。

  • 進程有進程式控制制塊PCB,系統通過PCB對進程進行調度。進程有線程式控制制塊TCP,但TCB所表示的狀態比PCB要少的多。

④ linux裡面,進程與線程到底有什麼本質的區別

線程:是進程中執行的一條路徑,是系統調度的最小單位。

進程:是正在運行的程序,是系統分配資源的最小單位。

線程與進程關系

1.一個進程可以有多個線程,一個線程只能屬於一個進程。

2.同一個進程下的所有線程共享該進程下的所有資源。

3.真正在處理機上運行的是線程,不是進程,線程是進程內的一個執行單元,是進程內的可調度實體。

Linux線程與進程區別

進程:

優點:多進程可以同時利用多個CPU,能夠同時進行多個操作。

缺點:耗費資源(創建一個進程重新開辟內存空間)。

進程不是越多越好,一般進程個數等於cpu個數。

線程:

優點:共享內存,尤其是進行IO操作(網路、磁碟)的時候(IO操作很少用cpu),可以使用多線程執行並發操作。

缺點:搶占資源。

⑤ linux下多進程或者多線程編程的問題。新手,望指教!

你好,多進程或多線程,都不會阻塞當前語句代碼。為了您的理解,我就大膽舉下面兩個例子:
多進程:你可以看成是本來是一條路的,現在從中間拆成兩條,然後每一條路都有屬於自己這條路的代碼在運行。
多線程:你可以看成是一條路,然後分出車道,比如左車道和右車道甚至是停車道,然後每條車道都單獨通車,其他車道的不能對這條車道進行干擾。

所以,把一條路從中間拆成兩條,成本是很高的。但是把一條路分車道,成本就不是很高了。
對於您提出的main函數的疑問,當main函數最後執行完畢,程序退出後,所有的進程包括線程,都會被關閉的,哪怕你的程序中沒有關閉,操作系統也會幫你關閉的,現在的操作系統都非常的完善了。當然,也存在有線程或進程不被釋放的特殊情況,最好在編程中要記得釋放。

⑥ Linux:如何使用gdb調試多進程多線程程序

  • follow-fork-mode

  • 在2.5.60版Linux內核及以後,GDB對使用fork/vfork創建子進程的程序提供了follow-fork-mode選項來支持多進程調試。

  • follow-fork-mode的用法為:

  • set follow-fork-mode [parent|child]

  • parent: fork之後繼續調試父進程,子進程不受影響。

  • child: fork之後調試子進程,父進程不受影響。

  • 因此如果需要調試子進程,在啟動gdb後:

  • (gdb) set follow-fork-mode child

  • 並在子進程代碼設置斷點。

  • 此外還有detach-on-fork參數,指示GDB在fork之後是否斷開(detach)某個進程的調試,或者都交由GDB控制:

  • set detach-on-fork [on|off]

  • on: 斷開調試follow-fork-mode指定的進程。

  • off: gdb將控制父進程和子進程。follow-fork-mode指定的進程將被調試,另一個進程置於暫停(suspended)狀態。

  • 注意,最好使用GDB 6.6或以上版本,如果你使用的是GDB6.4,就只有follow-fork-mode模式。

  • follow-fork-mode/detach-on-fork的使用還是比較簡單的,但由於其系統內核/gdb版本限制,我們只能在符合要求的系統上才能使用。而且,由於follow-fork-mode的調試必然是從父進程開始的,對於fork多次,以至於出現孫進程或曾孫進程的系統,例如上圖3進程系統,調試起來並不方便。

⑦ Linux 下多線程和多進程程序的優缺點,各自適合什麼樣的業務場景

Linux 下多線程和多進程程序的優缺點,各自適合什麼樣的業務場景
IBM有個傢伙做了個測試,發現切換線程context的時候,windows比linux快一倍多。進出最快的鎖(windows2k的 critical section和linux的pthread_mutex),windows比linux的要快五倍左右。當然這並不是說linux不好,而且在經過實際編程之後,綜合來看我覺得linux更適合做high performance server,不過在多線程這個具體的領域內,linux還是稍遜windows一點。這應該是情有可原的,畢竟unix家族都是從多進程過來的,而 windows從頭就是多線程的。
如果是UNIX/linux環境,採用多線程沒必要。
多線程比多進程性能高?誤導!
應該說,多線程比多進程成本低,但性能更低。
在UNIX環境,多進程調度開銷比多線程調度開銷,沒有顯著區別,就是說,UNIX進程調度效率是很高的。內存消耗方面,二者只差全局數據區,現在內存都很便宜,伺服器內存動輒若干G,根本不是問題。
多進程是立體交通系統,雖然造價高,上坡下坡多耗點油,但是不堵車。
多線程是平面交通系統,造價低,但紅綠燈太多,老堵車。
我們現在都開跑車,油(主頻)有的是,不怕上坡下坡,就怕堵車。
高性能交易伺服器中間件,如TUXEDO,都是主張多進程的。實際測試表明,TUXEDO性能和並發效率是非常高的。TUXEDO是貝爾實驗室的,與UNIX同宗,應該是對UNIX理解最為深刻的,他們的意見應該具有很大的參考意義。

⑧ linux 下 進程和線程的區別

線程是指進程內的一個執行單元,也是進程內的可調度實體.
與進程的區別:
(1)地址空間:進程內的一個執行單元;進程至少有一個線程;它們共享進程的地址空間;而進程有自己獨立的地址空間;
(2)資源擁有:進程是資源分配和擁有的單位,同一個進程內的線程共享進程的資源
(3)線程是處理器調度的基本單位,但進程不是.
4)二者均可並發執行.
進程和線程都是由操作系統所體會的程序運行的基本單元,系統利用該基本單元實現系統對應用的並發性。進程是系統進行資源分配和調度的一個獨立單位。線程是進程的一個實體,是CPU調度和分派的基本單位,線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。一個線程可以創建和撤銷另一個線程,同一個進程中的多個線程之間可以並發執行。

2.進程和應用程序的區別?

進程與應用程序的區別在於應用程序作為一個靜態文件存儲在計算機系統的硬碟等存儲空間中,而進程則是處於動態條件下由操作系統維護的系統資源管理實體。
C、C++、Java等語言編寫的源程序經相應的編譯器編譯成可執行文件後,提交給計算機處理器運行。這時,處在可執行狀態中的應用程序稱為進程。從用戶角度來看,進程是應用程序的一個執行過程。從操作系統核心角度來看,進程代表的是操作系統分配的內存、CPU時間片等資源的基本單位,是為正在運行的程序提供的運行環境。進程與應用程序的區別在於應用程序作為一個靜態文件存儲在計算機系統的硬碟等存儲空間中,而進程則是處於動態條件下由操作系統維護的系統資源管理實體。多任務環境下應用程序進程的主要特點包括: ●進程在執行過程中有內存單元的初始入口點,並且進程存活過程中始終擁有獨立的內存地址空間; ●進程的生存期狀態包括創建、就緒、運行、阻塞和死亡等類型; ●從應用程序進程在執行過程中向CPU發出的運行指令形式不同,可以將進程的狀態分為用戶態和核心態。處於用戶態下的進程執行的是應用程序指令、處於核心態下的應用程序進程執行的是操作系統指令

3.進程與Java線程的區別

應用程序在執行過程中存在一個內存空間的初始入口點地址、一個程序執行過程中的代碼執行序列以及用於標識進程結束的內存出口點地址,在進程執行過程中的每一時間點均有唯一的處理器指令與內存單元地址相對應。
Java語言中定義的線程(Thread)同樣包括一個內存入口點地址、一個出口點地址以及能夠順序執行的代碼序列。但是進程與線程的重要區別在於線程不能夠單獨執行,它必須運行在處於活動狀態的應用程序進程中,因此可以定義線程是程序內部的具有並發性的順序代碼流。 Unix操作系統和Microsoft Windows操作系統支持多用戶、多進程的並發執行,而Java語言支持應用程序進程內部的多個執行線程的並發執行。多線程的意義在於一個應用程序的多個邏輯單元可以並發地執行。但是多線程並不意味著多個用戶進程在執行,操作系統也不把每個線程作為獨立的進程來分配獨立的系統資源。進程可以創建其子進程,子進程與父進程擁有不同的可執行代碼和數據內存空間。而在用於代表應用程序的進程中多個線程共享數據內存空間,但保持每個線程擁有獨立的執行堆棧和程序執行上下文(Context)。
需要注意的是:在應用程序中使用多線程不會增加 CPU 的數據處理能力。只有在多CPU 的計算機或者在網路計算體系結構下,將Java程序劃分為多個並發執行線程後,同時啟動多個線程運行,使不同的線程運行在基於不同處理器的Java虛擬機中,才能提高應用程序的執行效率。 另外,如果應用程序必須等待網路連接或資料庫連接等數據吞吐速度相對較慢的資源時,多線程應用程序是非常有利的。基於Internet的應用程序有必要是多線程類型的,例如,當開發要支持大量客戶機的伺服器端應用程序時,可以將應用程序創建成多線程形式來響應客戶端的連接請求,使每個連接用戶獨佔一個客戶端連接線程。這樣,用戶感覺伺服器只為連接用戶自己服務,從而縮短了伺服器的客戶端響應時間。 三、Java語言的多線程程序設計方法

⑨ Linux下多線程和多進程程序的優缺點,各個適合什麼樣的業務場景

多進程比較安全,因為默認情況下不同進程之間的內存是獨立的(如果需要共享內存則需要進行進程間通信)。而多線程下,內存是共享的,這時就比較危險了,你要自己使用鎖、信號量等機制來解決內存塊的同時讀寫和同步等等。如果兩個功能沒有數據需要共享,或只有前後遞進關系,建議使用多進程。如果兩個功能需要同時對一塊數據進行處理(例如需要對資源進行創建和老化刪除),則需要使用多線程,這時可能需要使用鎖等機制來控制線程沖突。

⑩ 多線程vs多進程,誰在Linux能更好發揮多核CP

多線程和多進程應該是各有所長吧,它們都能很好的發揮處理器多核性能,對於多進程來說,Linux的進程是輕量級的,進程本身的資源開銷相當小,而且Linux的進程可以互相協作、互相發送消息、互相中斷,還可以共享內存段,編寫多個相互協作的進程也要比編寫多線程更容易,所以在Linux編程中多進程要比多線程更加常用一些。但是多進程之間共享變數不是很容易,它們畢竟是各自獨立的實體,而多線程可以很容易的共享變數(當然前提是搞好線程同步),所以會有一些資料庫伺服器程序用多線程技術,總之就是各有所長,根據編程的需要進行取捨。

熱點內容
java用什麼軟體寫 發布:2025-05-18 03:56:19 瀏覽:26
linux配置vim編譯c 發布:2025-05-18 03:55:07 瀏覽:99
砸百鬼腳本 發布:2025-05-18 03:53:34 瀏覽:934
安卓手機如何拍視頻和蘋果一樣 發布:2025-05-18 03:40:47 瀏覽:727
為什麼安卓手機連不上蘋果7熱點 發布:2025-05-18 03:40:13 瀏覽:797
網卡訪問 發布:2025-05-18 03:35:04 瀏覽:504
接收和發送伺服器地址 發布:2025-05-18 03:33:48 瀏覽:366
ef資料庫查詢數據 發布:2025-05-18 03:29:36 瀏覽:668
百度雲下載文件夾 發布:2025-05-18 03:17:33 瀏覽:674
php雲開發 發布:2025-05-18 03:12:41 瀏覽:447