當前位置:首頁 » 操作系統 » linuxtimewait

linuxtimewait

發布時間: 2022-05-18 11:21:33

『壹』 linux某個進程timewait了,怎麼查看其狀態

ps -fel可以看到所有的程序在運行中, 如果要查找特定的程序, 可以grep一下啊, 這個是linux系統的基本用法, 能看看wo的網名嗎?以後要是有linux系統的問題, 還可以一起解決哦

『貳』 linux下php使用curl導致大量TIME_WAIT求解決

如果提示`error: permission denied on key 'net.ipv4.tcp_tw_reuse''.請'su'到root並臨時關掉Selinux 'setenforce 0'

『叄』 linux time wait 什麼意思

linux time wait
時間等待
Linux是一套免費使用和自由傳播的類Unix操作系統,是一個基於POSIX和UNIX的多用戶、多任務、支持多線程和多CPU的操作系統。它能運行主要的UNIX工具軟體、應用程序和網路協議。它支持32位和64位硬體。Linux繼承了Unix以網路為核心的設計思想,是一個性能穩定的多用戶網路操作系統。
Linux操作系統誕生於1991 年10 月5 日(這是第一次正式向外公布時間)。Linux存在著許多不同的Linux版本,但它們都使用了Linux內核。Linux可安裝在各種計算機硬體設備中,比如手機、平板電腦、路由器、視頻游戲控制台、台式計算機、大型機和超級計算機。
嚴格來講,Linux這個詞本身只表示Linux內核,但實際上人們已經習慣了用Linux來形容整個基於Linux內核,並且使用GNU 工程各種工具和資料庫的操作系統。

『肆』 linux 如何強制關閉 time_wait 連接

# netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c
68 CLOSE_WAIT
2 CLOSING
136 ESTABLISHED
38 FIN_WAIT1
16 FIN_WAIT2
2 LAST_ACK
8 LISTEN
71 SYN_RECV
2936 TIME_WAIT
#
狀態:描述
CLOSED:無連接是活動的或正在進行
LISTEN:伺服器在等待進入呼叫
SYN_RECV:一個連接請求已經到達,等待確認
SYN_SENT:應用已經開始,打開一個連接
ESTABLISHED:正常數據傳輸狀態
FIN_WAIT1:應用說它已經完成
FIN_WAIT2:另一邊已同意釋放
ITMED_WAIT:等待所有分組死掉
CLOSING:兩邊同時嘗試關閉
TIME_WAIT:另一邊已初始化一個釋放
LAST_ACK:等待所有分組死掉

linux sysctl.conf close_wait

$ /proc/sys/net/core/wmem_max
最大socket寫buffer,可參考的優化值:873200

$ /proc/sys/net/core/rmem_max
最大socket讀buffer,可參考的優化值:873200

$ /proc/sys/net/ipv4/tcp_wmem
TCP寫buffer,可參考的優化值: 8192 436600 873200

$ /proc/sys/net/ipv4/tcp_rmem
TCP讀buffer,可參考的優化值: 32768 436600 873200

$ /proc/sys/net/ipv4/tcp_mem
同樣有3個值,意思是:
net.ipv4.tcp_mem[0]:低於此值,TCP沒有內存壓力.
net.ipv4.tcp_mem[1]:在此值下,進入內存壓力階段.
net.ipv4.tcp_mem[2]:高於此值,TCP拒絕分配socket.
上述內存單位是頁,而不是位元組.可參考的優化值是:786432 1048576 1572864

$ /proc/sys/net/core/netdev_max_backlog
進入包的最大設備隊列.默認是300,對重負載伺服器而言,該值太低,可調整到1000.

$ /proc/sys/net/core/somaxconn
listen()的默認參數,掛起請求的最大數量.默認是128.對繁忙的伺服器,增加該值有助於網路性能.可調整到256.

$ /proc/sys/net/core/optmem_max
socket buffer的最大初始化值,默認10K.

$ /proc/sys/net/ipv4/tcp_max_syn_backlog
進入SYN包的最大請求隊列.默認1024.對重負載伺服器,增加該值顯然有好處.可調整到2048.

$ /proc/sys/net/ipv4/tcp_retries2
TCP失敗重傳次數,默認值15,意味著重傳15次才徹底放棄.可減少到5,以盡早釋放內核資源.

$ /proc/sys/net/ipv4/tcp_keepalive_time

$ /proc/sys/net/ipv4/tcp_keepalive_intvl

$ /proc/sys/net/ipv4/tcp_keepalive_probes
這3個參數與TCP KeepAlive有關.默認值是:
tcp_keepalive_time = 3600 seconds (1 hours)
tcp_keepalive_probes = 3
tcp_keepalive_intvl = 60 seconds
意思是如果某個TCP連接在idle 2個小時後,內核才發起probe.
如果probe 3次(每次60秒)不成功,內核才徹底放棄,認為該連接已失效.
對伺服器而言,顯然上述值太大. 可調整到:
/proc/sys/net/ipv4/tcp_keepalive_time 120
/proc/sys/net/ipv4/tcp_keepalive_intvl 30
/proc/sys/net/ipv4/tcp_keepalive_probes 2

$ proc/sys/net/ipv4/ip_local_port_range
指定埠范圍的一個配置,默認是32768 61000,已夠大.
在大並發時可以調成1024 65535

下面是處理time_wait狀態時需要處理的一些參數.

net.ipv4.tcp_syncookies = 1
表示開啟SYN Cookies。當出現SYN等待隊列溢出時,啟用cookies來處理,可防範少量SYN攻擊,默認為0,表示關閉;

net.ipv4.tcp_tw_reuse = 1
表示開啟重用。允許將TIME-WAIT sockets重新用於新的TCP連接,默認為0,表示關閉;

net.ipv4.tcp_tw_recycle = 1
表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0,表示關閉。

net.ipv4.tcp_fin_timeout = 30
表示如果套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間。

net.ipv4.tcp_keepalive_time = 1200
表示當keepalive起用的時候,TCP發送keepalive消息的頻度。預設是2小時,改為20分鍾。

net.ipv4.ip_local_port_range = 1024 65000
表示用於向外連接的埠范圍。預設情況下很小:32768到61000,改為1024到65000。

net.ipv4.tcp_max_syn_backlog = 8192
表示SYN隊列的長度,默認為1024,加大隊列長度為8192,可以容納更多等待連接的網路連接數。

net.ipv4.tcp_max_tw_buckets = 5000
表示系統同時保持TIME_WAIT套接字的最大數量,如果超過這個數字,TIME_WAIT套接字將立刻被清除並列印警告信息。
默認為 180000,改為 5000。對於Apache、Nginx等伺服器,上面提到的參數可以很好地減少TIME_WAIT套接字數量,
避免Squid伺服器被大量的TIME_WAIT套接字拖死,此項參數可以控制TIME_WAIT套接字的最大數量。

『伍』 linux怎麼結束掉所有使用80埠的TIME_WAIT進程

要不等超時,要不重啟伺服器

通過修改Linux內核參數,可以減少伺服器的IME_WAIT套接字數量。

vi /etc/sysctl.conf
增加以下幾行:
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000

說明:
net.ipv4.tcp_syncookies = 1 表示開啟SYN Cookies。當出現SYN等待隊列溢出時,啟用cookies來處理,可防範少量SYN攻擊,默認為0,表示關閉;
net.ipv4.tcp_tw_reuse = 1 表示開啟重用。允許將TIME-WAIT sockets重新用於新的TCP連接,默認為0,表示關閉;
net.ipv4.tcp_tw_recycle = 1 表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0,表示關閉。
net.ipv4.tcp_fin_timeout = 30 表示如果套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間。
net.ipv4.tcp_keepalive_time = 1200 表示當keepalive起用的時候,TCP發送keepalive消息的頻度。預設是2小時,改為20分鍾。
net.ipv4.ip_local_port_range = 1024 65000 表示用於向外連接的埠范圍。預設情況下很小:32768到61000,改為1024到65000。
net.ipv4.tcp_max_syn_backlog = 8192 表示SYN隊列的長度,默認為1024,加大隊列長度為8192,可以容納更多等待連接的網路連接數。
net.ipv4.tcp_max_tw_buckets = 5000 表示系統同時保持TIME_WAIT套接字的最大數量,如果超過這個數字,TIME_WAIT套接字將立刻被清除並列印警告信息。默認為180000,改為5000。對於Apache、Nginx等伺服器,上幾行的參數可以很好地減少TIME_WAIT套接字數量,但是對於Squid,效果卻不大。此項參數可以控制TIME_WAIT套接字的最大數量,避免Squid伺服器被大量的TIME_WAIT套接字拖死。

執行以下命令使配置生效:
/sbin/sysctl -p

『陸』 探討如何減少Linux伺服器TIME

檢查net.ipv4.tcp_tw當前值,將當前的值更改為1分鍾:
[root@aaa1 ~]# sysctl -a|grep net.ipv4.tcp_tw
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_tw_recycle = 0
[root@aaa1 ~]#
vi /etc/sysctl

增加或修改net.ipv4.tcp_tw值:
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

使內核參數生效:
[root@aaa1 ~]# sysctl -p

[root@aaa1 ~]# sysctl -a|grep net.ipv4.tcp_tw
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

設置這兩個參數: reuse是表示是否允許重新應用處於TIME-WAIT狀態的socket用於新的TCP連接; recyse是加速TIME-WAIT sockets回收

用netstat再觀察正常
這里解決問題的關鍵是如何能夠重復利用time_wait的值,我們可以設置時檢查一下time和wait的值

#sysctl -a | grep time | grep wait
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120

這樣的現象實際是正常的,有時和訪問量大有關,設置這兩個參數: reuse是表示是否允許重新應用處於TIME-WAIT狀態的socket用於新的TCP連接; recyse是加速TIME-WAIT sockets回收。

net.ipv4.tcp_syncookies=1 打開TIME-WAIT套接字重用功能,對於存在大量連接的Web伺服器非常有效。
net.ipv4.tcp_tw_recyle=1
net.ipv4.tcp_tw_reuse=1 減少處於FIN-WAIT-2連接狀態的時間,使系統可以處理更多的連接。
net.ipv4.tcp_fin_timeout=30 減少TCP KeepAlive連接偵測的時間,使系統可以處理更多的連接。
net.ipv4.tcp_keepalive_time=1800 增加TCP SYN隊列長度,使系統可以處理更多的並發連接。
net.ipv4.tcp_max_syn_backlog=8192

net.ipv4.tcp_syncookies = 1
#表示開啟SYN Cookies。當出現SYN等待隊列溢出時,啟用cookies來處理,可防範少量SYN攻擊,默認為0,表示關閉;
net.ipv4.tcp_tw_reuse = 1
#表示開啟重用。允許將TIME-WAIT sockets重新用於新的TCP連接,默認為0,表示關閉;
net.ipv4.tcp_tw_recycle = 1
#表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0,表示關閉。
net.ipv4.tcp_fin_timeout = 30
#表示如果套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間。
net.ipv4.tcp_keepalive_time = 1200
#表示當keepalive起用的時候,TCP發送keepalive消息的頻度。預設是2小時,改為20分鍾。
net.ipv4.ip_local_port_range = 1024 65000
#表示用於向外連接的埠范圍。預設情況下很小:32768到61000,改為1024到65000。
net.ipv4.tcp_max_tw_buckets = 5000
#表示系統同時保持TIME_WAIT套接字的最大數量,如果超過這個數字,
#TIME_WAIT套接字將立刻被清除並列印警告信息。默認為180000,改為5000。
#對於Apache、Nginx等伺服器,上幾行的參數可以很好地減少TIME_WAIT套接字數量,
#但是對於Squid,效果卻不大。此項參數可以控制TIME_WAIT套接字的最大數量,避免Squid伺服器被大量的TIME_WAIT套接字拖死

『柒』 怎樣提高Linux系統的短連接負載能力

計算機用戶舍棄微軟,開始應用於是很多人開始應用Linux操作系統,學習Linux時,學習Linux,你可能會遇到Linux系統應對短連接的負載能力問題,這里將介紹Linux系統應對短連接的負載能力的解決方法,在這里拿出來和大家分享一下。在存在大量短連接的情況下,Linux的TCP棧一般都會生成大量的 TIME_WAIT 狀態的socket。
你可以用下面的命令看到:
netstat -ant| grep -i time_wait
有時候,這個數目是驚人的:
netstat -ant|grep -i time_wait |wc -l
可能會超過三四萬。這個時候,我們需要修改 Linux kernel 的 tcp time wait的時間,縮短之,有個 sysctl 參數貌似可以使用,它是 /proc/sys/net/ipv4/tcp_fin_timeout,預設值是 60,也就是60秒,很多網上的資料都說將這個數值設置低一些就可以減少netstat 裡面的TIME_WAIT狀態,但是這個說法是錯誤的。經過認真閱讀Linux的內核源代碼,我們發現這個數值其實是輸出用的,修改之後並沒有真正的讀回內核中進行使用,而內核中真正管用的是一個宏定義,在 $KERNEL/include/net/tcp.h裡面,有下面的行:
#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT * state, about 60 seconds */

而這個宏是真正控制 TCP TIME_WAIT 狀態的超時時間的。如果我們希望減少 TIME_WAIT 狀態的數目(從而節省一點點內核操作時間),那麼可以把這個數值設置低一些,根據我們的測試,設置為 10 秒比較合適,也就是把上面的修改為
#define TCP_TIMEWAIT_LEN (10*HZ) /* how long to wait to destroy TIME-WAIT * state, about 60 seconds */

然後重新編譯內核,重啟系統即可發現短連接造成的TIME_WAIT狀態大大減少:
netstat -ant | grep -i time_wait |wc -l
一般情況都可以至少減少2/3。也能相應提高系統應對短連接的速度。以上就是如何進行Linux系統應對短連接的負載能力介紹。

『捌』 誰來給我講一下linux系統編程里的「wait

linux查看連接數,並發數1、查看apache當前並發訪問數: netstat -an grep ESTABLISHED wc -l對比httpd.conf中MaxClients的數字差距多少。2、查看有多少個進程數:ps auxgrep httpdwc -l3、可以使用如下參數查看數據server-status?auto#ps -efgrep httpdwc -l1388統計httpd進程數,連個請求會啟動一個進程,使用於Apache伺服器。表示Apache能夠處理1388個並發請求,這個值Apache可根據負載情況自動調整。#netstat -natgrep -i 80wc -l4341netstat -an會列印系統當前網路鏈接狀態,而grep -i 80是用來提取與80埠有關的連接的,wc -l進行連接數統計。 最終返回的數字就是當前所有80埠的請求總數。#netstat -nagrep ESTABLISHEDwc -l376netstat -an會列印系統當前網路鏈接狀態,而grep ESTABLISHED 提取出已建立連接的信息。 然後wc -l統計。最終返回的數字就是當前所有80埠的已建立連接的總數。netstat -natgrep ESTABLISHEDwc - 可查看所有建立連接的詳細記錄 查看Apache的並發請求數及其TCP連接狀態:linux命令:netstat -n awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'返回結果示例:LAST_ACK 5SYN_RECV 30ESTABLISHED 1597FIN_WAIT1 51FIN_WAIT2 504TIME_WAIT 1057其中的SYN_RECV表示正在等待處理的請求數;ESTABLISHED表示正常數據傳輸狀態;TIME_WAIT表示處理完畢,等待超時結束的請求數。

『玖』 linux timewait比較多會有什麼問題

如果是做 server, 有可能會 socket耗盡

如果不是 server 那沒影響.

timewait 狀態表示對端已經發送 close, 而自己還沒有給對方響應, 在 4 分鍾後會釋放.

『拾』 linux 多進程信號同步問題

朋友你好:希望能幫到你。互相學習。
線程的最大特點是資源的共享性,但資源共享中的同步問題是多線程編程的難點。linux下提供了多種方式來處理線程同步,最常用的是互斥鎖、條件變數和信號量。
1)互斥鎖(mutex)
通過鎖機制實現線程間的同步。同一時刻只允許一個線程執行一個關鍵部分的代碼。
int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t *mutexattr);
int pthread_mutex_lock(pthread_mutex *mutex);
int pthread_mutex_destroy(pthread_mutex *mutex);
int pthread_mutex_unlock(pthread_mutex *
(1)先初始化鎖init()或靜態賦值pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIER
attr_t有:
PTHREAD_MUTEX_TIMED_NP:其餘線程等待隊列
PTHREAD_MUTEX_RECURSIVE_NP:嵌套鎖,允許線程多次加鎖,不同線程,解鎖後重新競爭
PTHREAD_MUTEX_ERRORCHECK_NP:檢錯,與一同,線程請求已用鎖,返回EDEADLK;
PTHREAD_MUTEX_ADAPTIVE_NP:適應鎖,解鎖後重新競爭
(2)加鎖,lock,trylock,lock阻塞等待鎖,trylock立即返回EBUSY
(3)解鎖,unlock需滿足是加鎖狀態,且由加鎖線程解鎖
(4)清除鎖,destroy(此時鎖必需unlock,否則返回EBUSY,//Linux下互斥鎖不佔用內存資源
示例代碼
#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
說明:pthread庫不是Linux系統默認的庫,連接時需要使用靜態庫libpthread.a,所以在使用pthread_create()創建線程,以及調用pthread_atfork()函數建立fork處理程序時,需要鏈接該庫。在編譯中要加 -lpthread參數。
2)條件變數(cond)
利用線程間共享的全局變數進行同步的一種機制。條件變數上的基本操作有:觸發條件(當條件變為 true 時);等待條件,掛起線程直到其他線程觸發條件。
int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr);
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);
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond); //解除所有線程的阻塞
(1)初始化.init()或者pthread_cond_t cond=PTHREAD_COND_INITIALIER(前者為動態初始化,後者為靜態初始化);屬性置為NULL
(2)等待條件成立.pthread_wait,pthread_timewait.wait()釋放鎖,並阻塞等待條件變數為真,timewait()設置等待時間,仍未signal,返回ETIMEOUT(加鎖保證只有一個線程wait)
(3)激活條件變數:pthread_cond_signal,pthread_cond_broadcast(激活所有等待線程)
(4)清除條件變數:destroy;無線程等待,否則返回EBUSY
對於
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
一定要在mutex的鎖定區域內使用。
如果要正確的使用pthread_mutex_lock與pthread_mutex_unlock,請參考
pthread_cleanup_push和pthread_cleanup_pop宏,它能夠在線程被cancel的時候正確的釋放mutex!
另外,posix1標准說,pthread_cond_signal與pthread_cond_broadcast無需考慮調用線程是否是mutex的擁有者,也就是說,可以在lock與unlock以外的區域調用。如果我們對調用行為不關心,那麼請在lock區域之外調用吧。
說明:
(1)pthread_cond_wait 自動解鎖互斥量(如同執行了pthread_unlock_mutex),並等待條件變數觸發。這時線程掛起,不佔用CPU時間,直到條件變數被觸發(變數為ture)。在調用 pthread_cond_wait之前,應用程序必須加鎖互斥量。pthread_cond_wait函數返回前,自動重新對互斥量加鎖(如同執行了pthread_lock_mutex)。
(2)互斥量的解鎖和在條件變數上掛起都是自動進行的。因此,在條件變數被觸發前,如果所有的線程都要對互斥量加鎖,這種機制可保證在線程加鎖互斥量和進入等待條件變數期間,條件變數不被觸發。條件變數要和互斥量相聯結,以避免出現條件競爭——個線程預備等待一個條件變數,當它在真正進入等待之前,另一個線程恰好觸發了該條件(條件滿足信號有可能在測試條件和調用pthread_cond_wait函數(block)之間被發出,從而造成無限制的等待)。
(3)pthread_cond_timedwait 和 pthread_cond_wait 一樣,自動解鎖互斥量及等待條件變數,但它還限定了等待時間。如果在abstime指定的時間內cond未觸發,互斥量mutex被重新加鎖,且pthread_cond_timedwait返回錯誤 ETIMEDOUT。abstime 參數指定一個絕對時間,時間原點與 time 和 gettimeofday 相同:abstime = 0 表示 1970年1月1日00:00:00 GMT。
(4)pthread_cond_destroy 銷毀一個條件變數,釋放它擁有的資源。進入 pthread_cond_destroy 之前,必須沒有在該條件變數上等待的線程。
(5)條件變數函數不是非同步信號安全的,不應當在信號處理程序中進行調用。特別要注意,如果在信號處理程序中調用 pthread_cond_signal 或pthread_cond_boardcast 函數,可能導致調用線程死鎖。
示常式序1
#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;

}
示常式序2:
#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;
/*[thread_func]*/

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);,再讀取資源

//用這個流程是比較清楚的/*block-->unlock-->wait() return-->lock*/

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;

}
3)信號量
如同進程一樣,線程也可以通過信號量來實現通信,雖然是輕量級的。
信號量函數的名字都以"sem_"打頭。線程使用的基本信號量函數有四個。
#include <semaphore.h>
int sem_init (sem_t *sem , int pshared, unsigned int value);
這是對由sem指定的信號量進行初始化,設置好它的共享選項(linux 只支持為0,即表示它是當前進程的局部信號量),然後給它一個初始值VALUE。
兩個原子操作函數:
int sem_wait(sem_t *sem);
int sem_post(sem_t *sem);
這兩個函數都要用一個由sem_init調用初始化的信號量對象的指針做參數。
sem_post:給信號量的值加1;
sem_wait:給信號量減1;對一個值為0的信號量調用sem_wait,這個函數將會等待直到有其它線程使它不再是0為止。
int sem_destroy(sem_t *sem);
這個函數的作用是再我們用完信號量後都它進行清理。歸還自己佔有的一切資源。
示例代碼:
#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;

}
通 過執行結果後,可以看出,會先執行線程二的函數,然後再執行線程一的函數。它們兩就實現了同步

熱點內容
java執行ftp命令 發布:2025-01-14 02:05:21 瀏覽:937
青檸檬編程 發布:2025-01-14 02:05:18 瀏覽:882
下載加密日記本 發布:2025-01-14 02:05:16 瀏覽:538
汽車的假配置有哪些 發布:2025-01-14 02:03:16 瀏覽:41
二次插值演算法 發布:2025-01-14 02:02:01 瀏覽:163
江西頁游伺服器雲主機 發布:2025-01-14 02:01:17 瀏覽:492
安卓配置描述文件在哪裡 發布:2025-01-14 01:51:21 瀏覽:260
android數據xml存儲 發布:2025-01-14 01:48:45 瀏覽:369
ueditorjava圖片上傳 發布:2025-01-14 01:48:00 瀏覽:639
伺服器硬碟如何安裝系統 發布:2025-01-14 01:38:10 瀏覽:11