導航:首頁 > 編程語言 > 5天玩轉c並行和多線程編程

5天玩轉c並行和多線程編程

發布時間:2024-06-01 00:11:34

A. 關於C++多線程編程教學

在Windows NT和Windows 9x中,多線程的編程實現需要調用一系列的API函數,如CreateThread、ResumeThread等,比較麻煩而且容易出錯。我們使用Inprise公司的新一代RAD開發工具C++Builder,可以方便地實現多線程的編程。與老牌RAD工具Visual Basic和Delphi比,C++Builer不僅功能非常強大,而且它的編程語言是C++,對於系統開發語言是C的Windows系列操作系統,它具有其它編程語言無可比擬的優勢。利用C++Builder提供的TThread對象,多線程的編程變得非常簡便易用。那麼,如何實現呢?且待我慢慢道來,讓你體會一下多線程的強大功能。

1. 創建多線程程序:

首先,先介紹一下實現多線程的具體步驟。在C++Builder中雖然用Tthread對象說明了線程的概念,但是Tthread對象本身並不完整,需要在TThread下新建其子類,並重載Execute方法來使用線程對象。在C++Builder下可以很方便地實現這一點。

在C++Builder IDE環境下選擇菜單File|New,在New欄中選中Thread Object,按OK,接下來彈出輸入框,輸入TThread對象子類的名字MyThread,這樣C++Builder自動為你創建了一個名為TMyThread的TThread子類。同時編輯器中多了一個名為Unit2.cpp的單元,這就是我們創建的TMyThread子類的原碼,如下:

#include
#pragma hdrstop

#include 「Unit2.h」
#pragma package(smart_init)
//---------------------
// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall MyThread::UpdateCaption()
// {
// Form1->Caption = 「Updated in a thread」;
// }
//--------------------
__fastcall MyThread::MyThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
//--------------------
void __fastcall MyThread::Execute()
{
//---- Place thread code here ----
}
//---------------------

其中的Execute()函數就是我們要在線程中實現的任務的代碼所在處。在原代碼中包含Unit2.cpp,這個由我們創建的TMyThread對象就可以使用了。使用時,動態創建一個TMyThread 對象,在構造函數中使用Resume()方法,那麼程序中就增加了一個新的我們自己定義的線程TMyThread,具體執行的代碼就是Execute()方法重載的代碼。要載入更多的線程,沒關系,只要繼續創建需要數量的TMyThread 對象就成。

B. Linux 多線程編程(二)2019-08-10

三種專門用於線程同步的機制:POSIX信號量,互斥量和條件變數.

在Linux上信號量API有兩組,一組是System V IPC信號量,即PV操作,另外就是POSIX信號量,POSIX信號量的名字都是以sem_開頭.

phshared參數指定信號量的類型,若其值為0,就表示這個信號量是當前進程的局部信號量,否則該信號量可以在多個進程之間共享.value值指定信號量的初始值,一般與下面的sem_wait函數相對應.

其中比較重要的函數sem_wait函數會以原子操作的方式將信號量的值減一,如果信號量的值為零,則sem_wait將會阻塞,信號量的值可以在sem_init函數中的value初始化;sem_trywait函數是sem_wait的非阻塞版本;sem_post函數將以原子的操作對信號量加一,當信號量的值大於0時,其他正在調用sem_wait等待信號量的線程將被喚醒.
這些函數成功時返回0,失敗則返回-1並設置errno.

生產者消費者模型:
生產者對應一個信號量:sem_t procer;
消費者對應一個信號量:sem_t customer;
sem_init(&procer,2)----生產者擁有資源,可以工作;
sem_init(&customer,0)----消費者沒有資源,阻塞;

在訪問公共資源前對互斥量設置(加鎖),確保同一時間只有一個線程訪問數據,在訪問完成後再釋放(解鎖)互斥量.
互斥鎖的運行方式:串列訪問共享資源;
信號量的運行方式:並行訪問共享資源;
互斥量用pthread_mutex_t數據類型表示,在使用互斥量之前,必須使用pthread_mutex_init函數對它進行初始化,注意,使用完畢後需調用pthread_mutex_destroy.

pthread_mutex_init用於初始化互斥鎖,mutexattr用於指定互斥鎖的屬性,若為NULL,則表示默認屬性。除了用這個函數初始化互斥所外,還可以用如下方式初始化:pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER。
pthread_mutex_destroy用於銷毀互斥鎖,以釋放佔用的內核資源,銷毀一個已經加鎖的互斥鎖將導致不可預期的後果。

pthread_mutex_lock以原子操作給一個互斥鎖加鎖。如果目標互斥鎖已經被加鎖,則pthread_mutex_lock則被阻塞,直到該互斥鎖佔有者把它給解鎖.
pthread_mutex_trylock和pthread_mutex_lock類似,不過它始終立即返回,而不論被操作的互斥鎖是否加鎖,是pthread_mutex_lock的非阻塞版本.當目標互斥鎖未被加鎖時,pthread_mutex_trylock進行加鎖操作;否則將返回EBUSY錯誤碼。注意:這里討論的pthread_mutex_lock和pthread_mutex_trylock是針對普通鎖而言的,對於其他類型的鎖,這兩個加鎖函數會有不同的行為.
pthread_mutex_unlock以原子操作方式給一個互斥鎖進行解鎖操作。如果此時有其他線程正在等待這個互斥鎖,則這些線程中的一個將獲得它.


三個列印機輪流列印:

輸出結果:

如果說互斥鎖是用於同步線程對共享數據的訪問的話,那麼條件變數就是用於在線程之間同步共享數據的值.條件變數提供了一種線程之間通信的機制:當某個共享數據達到某個值時,喚醒等待這個共享數據的線程.
條件變數會在條件不滿足的情況下阻塞線程.且條件變數和互斥量一起使用,允許線程以無競爭的方式等待特定的條件發生.

其中pthread_cond_broadcast函數以廣播的形式喚醒所有等待目標條件變數的線程,pthread_cond_signal函數用於喚醒一個等待目標條件變數線程.但有時候我們可能需要喚醒一個固定的線程,可以通過間接的方法實現:定義一個能夠唯一標識目標線程的全局變數,在喚醒等待條件變數的線程前先設置該變數為目標線程,然後採用廣播的方式喚醒所有等待的線程,這些線程被喚醒之後都檢查該變數以判斷是否是自己.

採用條件變數+互斥鎖實現生產者消費者模型:

運行結果:

阻塞隊列+生產者消費者

運行結果:

C. 什麼是多線程編程

多線程編程技術是java語言的重要特點。多線程編程的含義是將程序任務分成幾個並行的子任務。特別是在網路編程中,你會發現很多功能是可以並發執行的。 比如網路傳輸速度較慢、用戶輸入速度較慢,你可以用兩個獨立的線程去完成這兩個功能,而不影響正常的顯示或其它功能。 多線程是與單線程比較而言的,普通的Windows採用單線程程序結構,其工作原理是:主程序有一個消息循環,不斷從消息隊列中讀入消息來決定下一步所要乾的事情,一般是針對一個函數,只有等這個函數執行完之後,主程序才能接收另外的消息來執行。比如子函數功能是在讀一個網路數據,或讀一個文件,只有等讀完這個數據或文件才能接收下一個消息。在執行這個子函數過程中你什麼也不能幹。但往往讀網路數據和等待用戶輸入有很多時間處於等待狀態,多線程利用這個特點將任務分成多個並發任務後,就可以解決這個問題。Java中的線程類 1.擴展java.lang.Thread類,用它覆蓋Thread類的run方法。 2.生成實現java.lang.Runnable介面的類並將其它的實例與java.lang.Thread實例相關聯。 Thread類是負責向其它類提供線程支持的最主要的類,要使用一個類具有線程功能,在Java中只要簡單地從Thread類派生一個子類就可以了擴展Thread類,如printThread.java。 Thread類最重要的方法是run方法。run方法是新線程執行的方法,因此生成java.lang.Thread的子類時,必須有相應的run方法。 //PrintThread.java public class PrintThread extends Thread//繼承Tread類 private int count=0 //定義一個count變數用於統計列印的次數並共享變數 public static void mainString args//main方法開始 PrintThread p=new PrintThread//創建一個線程實例 p.start//執行線程 for{;;}//主線程main方法執行一個循環,for執行一個死循環count++ System.out.printcount+″:Main\n″//主線程中列印count +「main」變數的值,並換行 public void run//線程類必須有的run()方法for{;;}count++ System.out.printcount+″:Thread\n″ 上面這段程序便是繼承java.lang.Tread並覆蓋run的方法。用Java 虛擬機啟動程序時,這個程序會先生成一個線程並調用程序主類的main方法。這個程序中的main方法生成新線程,連接列印「Thread」。在啟動線程之後,主線程繼續列印「Main」。 編譯並執行這個程序,然後立即按「Ctrl+C」鍵中斷程序,你會看到上面所述的兩個線程不斷列印出:XXX:main…..XXX:Thread…. XXX代表的是數字,也就是上面count的值。在筆者的機器上,不同時刻這兩個線程列印的次數不一樣,先列印20個main(也就是先執行20次主線程)再列印出50次Thread,然後再列印main…… 提示:為了便於查看該程序的執行結果,你可以將執行結果導入一個文本文件,然後打開這個文件查看各線程執行的情況。如運行: javac PrintThread.java Java PrintThread1.txt 第一個命令javac PrintThread.java是編譯java程序,第二個是執行該程序並將結果導入1.txt文件。當然你可以直接執行命令:java

D. C語言基礎網路編程求助 如何實現多線程

#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

void*thread(void*);
int client[5],i;

main()
{
int serverSocket= socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server_addr;
struct sockaddr_in clientAddr;
int addr_len = sizeof(clientAddr);
//線程
pthread_t id;
pthread_attr_t attr;
pthread_attr_init(&attr);////////////////////////////////////////////////
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
//創建地址
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family =AF_INET;
server_addr.sin_port = htons(5555);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//綁定
bind(serverSocket,(struct sockaddr *)&server_addr,sizeof(server_addr));
listen(serverSocket,5);
for(i=0;i<5;i++)
{
client[i] = accept(serverSocket,(struct sockaddr *)&clientAddr,(socklen_t*)&addr_len);
pthread_create(&id,&attr,thread,(void *)&client[i]);/////////////////////////////////
pthread_join(id,NULL);
}
close(serverSocket);/////////////////////////
return 0;
}
void* thread(void* argv)
{
char buffer[200];
int a=i;
int s_c = *((int*)argv);///////////////////
while(1)
{
int n = recv(s_c,buffer,sizeof(buffer),0);
if(n > 0)
printf("客戶端發過來的 : %s\n",buffer);
else
return;
}
close(s_c);
}

E. C++多線程編程問題

多線程工作可以提高解決問題的速度

你舉得例子可以多線程實現,但是更多的人稱之為分布式計算
多線程主要是創建多個線程,每個線程負責自己的事情,每個線程只對主線程負責
至於解決問題的速度應該可以達到提高一半,但是你要注意資源的互斥,互斥處理不好估計會事倍功半

閱讀全文

與5天玩轉c並行和多線程編程相關的資料

熱點內容
伺服器安全保護是什麼意思 瀏覽:787
刪除運行命令 瀏覽:718
龍之召喚伺服器如何 瀏覽:119
linux目錄跳轉 瀏覽:368
程序員和老闆稱兄道弟 瀏覽:759
直播網路連接源碼 瀏覽:736
用安卓手機怎麼登錄蘋果手機id 瀏覽:710
論文查重工具源碼 瀏覽:401
android銀聯demo 瀏覽:86
智能演算法發展 瀏覽:351
房車露營地用什麼app 瀏覽:70
spark編程指南python 瀏覽:553
phparray源碼 瀏覽:1002
安卓手機反應有點慢怎麼辦 瀏覽:705
c語言怎麼訪問伺服器並獲取數據 瀏覽:114
怎麼下載三維app 瀏覽:77
把pdf中的圖片導出到excel 瀏覽:505
php操作redis實例 瀏覽:143
蘋果app怎麼綁卡 瀏覽:979
便簽加密的筆記在哪裡打開 瀏覽:845