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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

linux c 多线程 popen(linux c 多线程)

發(fā)布時(shí)間:2023/12/4 综合教程 28 生活家
生活随笔 收集整理的這篇文章主要介紹了 linux c 多线程 popen(linux c 多线程) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

c語言有沒有多線程這個(gè)概念?

線程:線程是程序中的一個(gè)執(zhí)行流,每個(gè)線程都有自己的專有寄存器(棧指針、程序計(jì)數(shù)器等),但代碼區(qū)是共享的,即不同的線程可以執(zhí)行同樣的函數(shù)。

多線程:多線程是指程序中包含多個(gè)執(zhí)行流,即在一個(gè)程序中可以同時(shí)運(yùn)行多個(gè)不同的線程來執(zhí)行不同的任務(wù),也就是說允許單個(gè)程序創(chuàng)建多個(gè)并行執(zhí)行的線程來完成各自的任務(wù)。

C語言的開始設(shè)計(jì),并未設(shè)計(jì)多線程的機(jī)制,由于隨著軟硬件的發(fā)展及需求的發(fā)展。后來C語言才開發(fā)了線程庫以支持多線程的操作、應(yīng)用。

主要基于Linux介紹C多線程。在編譯C的多線程時(shí)候,一方面必須指定Linux C語言線程庫多線程庫pthread,才可以正確編譯(例如:gcc test.c -o test -lpthread);另一方面要包含有關(guān)線程頭文件#include

linux怎么指定線程庫?

大概的介紹一下Linux 的指定CPU運(yùn)行,包括進(jìn)程和線程。linux下的top命令是可以查看當(dāng)前的cpu的運(yùn)行狀態(tài),按1可以查看系統(tǒng)有多少個(gè)CPU,以及每個(gè)CPU的運(yùn)行狀態(tài)。 可是如何查看線程的CPU呢?

top -Hp pid,pid就是你當(dāng)前程序的進(jìn)程號,如果是多線程的話,是可以查看進(jìn)程內(nèi)所有線程的CPU和內(nèi)存使用情況。

pstree可以查看主次線程,同樣的pstree -p pid。可以查看進(jìn)程的線程情況。

taskset這個(gè)其實(shí)才是重點(diǎn),可以查看以及設(shè)置當(dāng)前進(jìn)程或線程運(yùn)行的CPU(設(shè)置親和力)。

taskset -pc pid,查看當(dāng)前進(jìn)程的cpu,當(dāng)然有的時(shí)候不只是一個(gè),taskset -pc cpu_num pid ,cpu_num就是設(shè)置的cpu。 這樣的話基本的命令和操作其實(shí)大家都知道了,接下來就是在代碼中完成這些操作,并通過命令去驗(yàn)證代碼的成功率。 進(jìn)程制定CPU運(yùn)行:

view plain copy #include #include #include #include #include #define __USE_GNU #include #include #include int main(int argc, char* argv) { //sysconf獲取有幾個(gè)CPU int num = sysconf(_SC_NPROCESSORS_CONF); int created_thread = 0; int myid; int i; int j = 0; //原理其實(shí)很簡單,就是通過cpu_set_t進(jìn)行位與操作 cpu_set_t mask; cpu_set_t get; if (argc != 2) { printf("usage : ./cpu numn"); exit(1); } myid = atoi(argv)

; printf("system has %i processor(s). n", num)

; //先進(jìn)行清空,然后設(shè)置掩碼 CPU_ZERO(&mask); CPU_SET(myid, &mask)

; //設(shè)置進(jìn)程的親和力 if (sched_setaffinity(0, sizeof(mask), &mask) == -1) { printf("warning: could not set CPU affinity, continuing...n"); } while (1) { CPU_ZERO(&get); //獲取當(dāng)前進(jìn)程的親和力 if (sched_getaffinity(0, sizeof(get), &get) == -1) { printf("warning: cound not get cpu affinity, continuing...n"); } for (i = 0; i < num; i++) { if (CPU_ISSET(i, &get)) { printf("this process %d is running processor : %dn",getpid(), i); } } } return 0; } 進(jìn)程設(shè)置CPU運(yùn)行,其實(shí)只能是單線程。多線程設(shè)定CPU如下:

view plain copy #define _GNU_SOURCE #include #include #include #include #include #include void *myfun(void *arg) { cpu_set_t mask; cpu_set_t get; char buf; int i; int j; //同樣的先去獲取CPU的個(gè)數(shù) int num = sysconf(_SC_NPROCESSORS_CONF); printf("system has %d processor(s)n", num); for (i = 0; i < num; i++) { CPU_ZERO(&mask); CPU_SET(i, &mask); //這個(gè)其實(shí)和設(shè)置進(jìn)程的親和力基本是一樣的 if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) { fprintf(stderr, "set thread affinity failedn"); } CPU_ZERO(&get); if (pthread_getaffinity_np(pthread_self(), sizeof(get), &get) < 0) { fprintf(stderr, "get thread affinity failedn"); } for (j = 0; j < num; j++) { if (CPU_ISSET(j, &get)) { printf("thread %d is running in processor %dn", (int)pthread_self(), j); } } j = 0; while (j++ < 100000000) { memset(buf, 0, sizeof(buf)); } } pthread_exit(NULL); } int main(int argc, char *argv) { pthread_t tid; if (pthread_create(&tid, NULL, (void *)myfun, NULL) != 0) { fprintf(stderr, "thread create failedn"); return -1; } pthread_join(tid, NULL); return 0; }

php多線程教程?

PHP+shell實(shí)現(xiàn)多線程的方法

先寫個(gè)簡單的php代碼,這里為了讓腳本執(zhí)行時(shí)間更長,方便看效果,sleep一下,呵呵!先看下test.php的代碼:ls

PHP代碼:

for ($i=0;$i<10;$i++) {

echo $i;

sleep(10);

}

?>

在看下shell腳本的代碼,非常簡單

#!/bin/bash

for i in 1 2 3 4 5 6 7 8 9 10

do

/usr/bin/php -q /var/www/html/test.php &

done

注意到在請求php代碼的那行有一個(gè)&符號嗎,這個(gè)是關(guān)鍵,不加的話是不能進(jìn)行多線程的,&表示講服務(wù)推送到后臺(tái)執(zhí)行,因此,在 shell的每次的循環(huán)中不必等php的代碼全部執(zhí)行完在請求下一個(gè)文件,而是同時(shí)進(jìn)行的,這樣就實(shí)現(xiàn)了多線程,下面運(yùn)行下shell看下效果,這里你將 看到10個(gè)test.php進(jìn)程再跑,再利用linux的定時(shí)器,定時(shí)請求這個(gè)shell,在處理一些需要多線程的任務(wù),例如,批量下載時(shí),非常好用!

php中用WEB服務(wù)器實(shí)現(xiàn)多線程

假設(shè)我們現(xiàn)在運(yùn)行的是a.php這個(gè)文件. 但是我在程序中又請求WEB服務(wù)器運(yùn)行另一個(gè)b.php,那么這兩個(gè)文件將是同時(shí)執(zhí)行的.(PS: 一個(gè)鏈接請求發(fā)送之后, WEB服務(wù)器就會(huì)執(zhí)行它, 而不管客戶端是否已經(jīng)退出)

有些時(shí)候, 我們想運(yùn)行的不是另一個(gè)文件, 而是本文件中的一部分代碼.該怎么辦呢?

其實(shí)可是通過參數(shù)來控制a.php來運(yùn)行哪一段程序.

下面看一個(gè)例子:

//a.php,b.php

PHP代碼:--------------------------------------------------------------------------------

function runThread()

{

$fp = fsockopen('localhost', 80, $errno, $errmsg);

fputs($fp, "GET /b.php?act=brnrn"); //這里的第二個(gè)參數(shù)是HTTP協(xié)議中規(guī)定的請求頭

//不明白的請看RFC中的定義

fclose($fp);

}

function a()

{

$fp = fopen('result_a.log', 'w');

fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");

fclose($fp);

}

function b()

{

$fp = fopen('result_b.log', 'w');

fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");

fclose($fp);

}

if(!isset($_GET)) $_GET = 'a';

if($_GET == 'a')

{

runThread();

a();

}

else if($_GET == 'b') b();

?>

--------------------------------------------------------------------------------

打開result_a.log 和 result_b.log 比較一下兩個(gè)文件的中訪問的時(shí)間. 大家會(huì)發(fā)現(xiàn), 這兩個(gè)的確是在不同線程中運(yùn)行的.有些時(shí)間完全一樣.

上面只是一個(gè)簡單的例子, 大家可以改進(jìn)成其它形式.

既然PHP中也能多線程了, 那么問題也來了, 那就是同步的問題. 我們知道 PHP本身是不支持多線程的. 所以更不會(huì)有什么像Java 中synchronize的方法了. 那我們該如何做呢.

1. 盡量不訪問同一個(gè)資源. 以避免沖突. 但是可以同時(shí)像數(shù)據(jù)庫操作. 因?yàn)閿?shù)據(jù)庫是支持并發(fā)操作的. 所以在多線程的PHP中不要向同一個(gè)文件中寫入數(shù)據(jù). 如果必須要寫的話, 用別的方法進(jìn)行同步.. 如調(diào)用 flock對文件進(jìn)行加鎖等. 或建立臨時(shí)文件并在另外的線程中等待這個(gè)文件的消失 while(file_exits('xxx')); 這樣就等于這個(gè)臨時(shí)文件存在時(shí), 表示其實(shí)線程正在操作

如果沒有了這個(gè)文件, 說明其它線程已經(jīng)釋放了這個(gè).

2. 盡量不要從runThread在執(zhí)行fputs后取這個(gè)socket中讀取數(shù)據(jù). 因?yàn)橐獙?shí)現(xiàn)多線程, 需要的用非阻塞模式. 即在像fgets這樣的函數(shù)時(shí)立即返回.. 所以讀寫數(shù)據(jù)就會(huì)出問題. 如果使用阻塞模式的話, 程序就不算是多線程了. 他要等上面的返回才執(zhí)行下面的程序. 所以如果需要交換數(shù)據(jù)最后利用外面文件或數(shù)據(jù)中完成. 實(shí)在想要的話就用socket_set_nonblock($fp) 來實(shí)現(xiàn).

說了這么多, 倒底這個(gè)有沒有實(shí)際的意義呢? 在什么時(shí)候需要這種用這種方法呢 ?

答案是肯定的. 大家知道. 在一個(gè)不斷讀取網(wǎng)絡(luò)資源的應(yīng)用中, 網(wǎng)絡(luò)的速度是瓶頸. 如果采多這種形式就可以同時(shí)以多個(gè)線程對不同的頁面進(jìn)行讀取.

本人做的一個(gè)能從8848、soaso這些商城網(wǎng)站搜索信息的程序。還有一個(gè)從阿里巴巴網(wǎng)站上讀取商業(yè)信息和公司目錄的程序也用到了此技術(shù)。 因?yàn)檫@兩個(gè)程序都是要不斷的鏈接它們的服務(wù)器讀取信息并保存到數(shù)據(jù)庫。 利用此技術(shù)正好消除了在等待響應(yīng)時(shí)的瓶頸。

php模擬實(shí)現(xiàn)多線程的三種方法

PHP語言本身是不支持多線程的. 總結(jié)了一下網(wǎng)上關(guān)于PHP模擬多線程的方法, 總的來說, 都是利用了PHP的好伙伴們本身所具有的多線程能力. PHP的好伙伴指的就是LINUX和APACHE啦, LAMP嘛.

另外, 既然是模擬的, 就不是真正的多線程. 其實(shí)只是多進(jìn)程. 進(jìn)程和線程是兩個(gè)不同的概念. 好了, 以下方法都是從網(wǎng)上找來的.

1. 利用LINUX操作系統(tǒng)

for ($i=0;$i<10;$i++) {

echo $i;

sleep(5);

}

?>

上面存成test.php, 然后寫一段SHELL代碼

#!/bin/bash

for i in 1 2 3 4 5 6 7 8 9 10

do

php -q test.php &

done

2. 利用fork子進(jìn)程(其實(shí)同樣是利用LINUX操作系統(tǒng))

declare(ticks=1);

$bWaitFlag = FALSE; /// 是否等待進(jìn)程結(jié)束

$intNum = 10; /// 進(jìn)程總數(shù)

$pids = array(); /// 進(jìn)程PID數(shù)組

echo ("Startn");

for($i = 0; $i < $intNum; $i++) {

$pids = pcntl_fork();/// 產(chǎn)生子進(jìn)程,而且從當(dāng)前行之下開試運(yùn)行代碼,而且不繼承父進(jìn)程的數(shù)據(jù)信息

if(!$pids) {

// 子進(jìn)程進(jìn)程代碼段_Start

$str="";

sleep(5+$i);

for ($j=0;$j<$i;$j++) {$str.="*";}

echo "$i -> " . time() . " $str n";

exit();

// 子進(jìn)程進(jìn)程代碼段_End

}

}

if ($bWaitFlag)

{

for($i = 0; $i < $intNum; $i++) {

pcntl_waitpid($pids, $status, WUNTRACED);

echo "wait $i -> " . time() . "n";

}

}

echo ("Endn");

?>

3. 利用WEB SERVER, PHP不支持多線程, APACHE可是支持的, 呵呵.

假設(shè)我們現(xiàn)在運(yùn)行的是a.php這個(gè)文檔. 但是我在程式中又請求WEB服務(wù)器運(yùn)行另一個(gè)b.php

那么這兩個(gè)文檔將是同時(shí)執(zhí)行的.(代碼同上)

當(dāng)然啦,也可以把需要多線程處理的部分交給JAVA去處理, 然后在PHP里調(diào)用, 哈哈.

system('java multiThread.java');

?>

擴(kuò)展資料:PHP即“超文本預(yù)處理器”,是一種通用開源腳本語言。PHP是在服務(wù)器端執(zhí)行的腳本語言,與C語言類似,是常用的網(wǎng)站編程語言。PHP獨(dú)特的語法混合了C、Java、Perl以及 PHP 自創(chuàng)的語法。利于學(xué)習(xí),使用廣泛,主要適用于Web開發(fā)領(lǐng)域。

linux下C中怎么讓才能安全關(guān)閉線程?

這個(gè)問題,首先得搞清楚線程關(guān)閉或者退出有哪些方式

線程的退出方式

如果進(jìn)程中的任何線程調(diào)用exit,_Exit或_exit,則整個(gè)進(jìn)程終止。 類似地,當(dāng)信號的默認(rèn)操作是終止進(jìn)程時(shí),發(fā)送到線程的信號將終止整個(gè)進(jìn)程。單個(gè)線程可以有三種方式退出其控制流程,而不會(huì)終止整個(gè)進(jìn)程。

1線程可以簡單地從線程處理程序中返回,返回值是線程的退出代碼。

2該線程可以被同一進(jìn)程中的另一個(gè)線程取消。

3該線程可以調(diào)用pthread_exi

線程退出的返回值

#include <pthread.h> void pthread_exit(void *rval_ptr);
#include <pthread.h> int pthread_join(pthread_t thread, void **rval_ptr);

pthread_join函數(shù)的rval_ptr參數(shù)是無類型指針。進(jìn)程中的其他線程可通過調(diào)用pthread_join函數(shù)來使用rval_ptr指針,調(diào)用它線程將阻塞,直到指定的線程調(diào)用pthread_exit或從其線程處理程序中返回或被取消。如果只是從其線程處理程序返回,則rval_ptr將包含返回碼。如果線程被取消,則rval_ptr指定的內(nèi)存位置設(shè)置為PTHREAD_CANCELED。

通過調(diào)用pthread_join,自動(dòng)會(huì)將加入的線程放置在分離狀態(tài),如果線程已處于分離狀態(tài),則pthread_join可能會(huì)失敗,返回EINVAL。如果我們對線程的返回值不感興趣,我們可以將rval_ptr設(shè)置為NULL。在這種情況下,調(diào)用pthread_join允許我們等待指定的線程,但不去檢索線程的終止?fàn)顟B(tài)。

下圖顯示了如何從已終止的線程中獲取退出代碼

運(yùn)行結(jié)果:

lj@lj-PC:~$ ./ptest

thread 1 returning

thread 2 exiting

thread 1 exit code 1

thread 2 exit code 2

線程如何取消

一個(gè)線程可以通過調(diào)用pthread_cancel函數(shù)請求取消同一進(jìn)程中的另一個(gè)。

#include <pthread.h>
int pthread_cancel(pthread_t tid);

在默認(rèn)情況下,pthread_cancel將使tid指定的線程的行為就像它使用PTHREAD_CANCELED參數(shù)調(diào)用pthread_exit一樣。 但是,線程可以選擇忽略或以其他方式控制取消的方式。 請注意,pthread_cancel不會(huì)等待線程終止。

線程可以安排函數(shù)在退出時(shí)被調(diào)用,這些函數(shù)稱為線程清理處理程序。 可以為一個(gè)線程建立多個(gè)清理處理程序。 處理程序記錄在堆棧中,這意味著它們的執(zhí)行順序與它們注冊的順序相反。

#include <pthread.h>
void pthread_cleanup_push(void (*rtn)(void *), void *arg);
void pthread_cleanup_pop(int execute);

當(dāng)線程執(zhí)行以下操作之一時(shí),pthread_cleanup_push函數(shù)會(huì)被調(diào)用

調(diào)用pthread_exit

回復(fù)取消請求

使用非零執(zhí)行參數(shù)調(diào)用pthread_cleanup_pop

如果execute參數(shù)設(shè)置為零,則不會(huì)調(diào)用cleanup函數(shù)。 在任何一種情況下,pthread_cleanup_pop都會(huì)刪除最后一次調(diào)用pthread_cleanup_push所建立的清理處理程序。

下圖舉例如何使用線程清理處理程序。

運(yùn)行結(jié)果:

lj@lj-PC:~$ ./pclean

thread 1 start

thread 1 push complete

thread 2 start

thread 1 exit code 1

thread 2 push complete

cleanup: thread 2 second handler

cleanup: thread 2 first handler

thread 2 exit code 2

從輸出中,我們可以看到兩個(gè)線程都正常啟動(dòng)并退出,但只調(diào)用了第二個(gè)線程的清理處理程序。因此,如果線程是通過其處理函數(shù)直接返回而終止,則不會(huì)調(diào)用其清理處理程序,不過此行為在具體平臺(tái)實(shí)現(xiàn)之間會(huì)有所不同。另請注意,清理處理程序的調(diào)用順序與安裝它們的順序相反。

如果我們在FreeBSD或Mac OS X上運(yùn)行相同的程序,我們會(huì)發(fā)現(xiàn)該程序會(huì)導(dǎo)致段錯(cuò)誤。發(fā)生這種情況是因?yàn)樵谶@些系統(tǒng)上,pthread_cleanup_push實(shí)現(xiàn)為在堆棧上存儲(chǔ)某些上下文的宏。當(dāng)線程1在對pthread_cleanup_push的調(diào)用和對pthread_cleanup_pop的調(diào)用之間返回時(shí),堆棧被覆蓋,并且這些平臺(tái)在調(diào)用清理處理程序時(shí)嘗試使用此(已損壞的)上下文。在Single UNIX Specification中,在對pthread_cleanup_push和pthread_cleanup_pop的一對匹配調(diào)用之間返回會(huì)導(dǎo)致未定義的行為。在這兩個(gè)函數(shù)之間返回的唯一可移植方法是調(diào)用pthread_exit。

線程和進(jìn)程的類似操作

從上文我們可以看到線程和進(jìn)程的相似之處,見如下表格:

講了這么多,還有好多細(xì)節(jié)沒有講到,只要詳細(xì)的了解了這些細(xì)節(jié),我相信關(guān)于你的這個(gè)問題“l(fā)inux下C中怎么讓才能安全關(guān)閉線程”自然就有了答案。

uc編程什么意思?

UC編程指Unix 的系統(tǒng)函數(shù)和 Unix 系統(tǒng)的設(shè)計(jì)和管理機(jī)制

內(nèi)容包括:

1. Unix Linux 的靜態(tài)庫 和共享庫

2.C語言的錯(cuò)誤處理

3.環(huán)境變量和環(huán)境表

4.Unix Linux 的內(nèi)存管理

5.Unix Linux 的文件操作

6.Unix Linux 的目錄操作

7.Unix Linux 的進(jìn)程管理

8.Unix Linux 的信號處理

9.IPC - 進(jìn)程間通信(共享內(nèi)存,消息隊(duì)列)

10.Unix Linux 的網(wǎng)絡(luò)編程

11.Unix Linux 的多線程開發(fā)

總結(jié)

以上是生活随笔為你收集整理的linux c 多线程 popen(linux c 多线程)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。