A. Java並發編程:如何創建線程,進程
在java中如果要創建線程的話,一般有兩種方式:1)繼承Thread類;2)實現Runnable介面。
1.繼承Thread類
繼承Thread類的話,必須重寫run方法,在run方法中定義需要執行的任務。
123456789101112
class MyThread extends Thread{ private static int num = 0; public MyThread(){ num++; } @Override public void run() { System.out.println("主動創建的第"+num+"個線程"); }}
創建好了自己的線程類之後,就可以創建線程對象了,然後通過start()方法去啟動線程。注意,不是調用run()方法啟動線程,run方法中只是定義需要執行的任務,如果調用run方法,即相當於在主線程中執行run方法,跟普通的方法調用沒有任何區別,此時並不會創建一個新的線程來執行定義的任務。public class Test { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); }} class MyThread extends Thread{ private static int num = 0; public MyThread(){ num++; } @Override public void run() { System.out.println("主動創建的第"+num+"個線程"); }}
在上面代碼中,通過調用start()方法,就會創建一個新的線程了。為了分清start()方法調用和run()方法調用的區別,請看下面一個例子:
212223
public class Test { public static void main(String[] args) { System.out.println("主線程ID:"+Thread.currentThread().getId()); MyThread thread1 = new MyThread("thread1"); thread1.start(); MyThread thread2 = new MyThread("thread2"); thread2.run(); }} class MyThread extends Thread{ private String name; public MyThread(String name){ this.name = name; } @Override public void run() { System.out.println("name:"+name+" 子線程ID:"+Thread.currentThread().getId()); }
B. 在linux中用一個進程創建3個線程,在三個線程分別列印各自的線程id
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#define THREAD_NUM 3
void * thread_handler(void *arg);
void main()
{
int i;
pthread_t tid[THREAD_NUM];
for(i = 0; i < THREAD_NUM; i++){
pthread_create(&tid[i], NULL, thread_handler, NULL);
}
for(i = 0; i < THREAD_NUM; i++){
pthread_join(tid[i],NULL);
}
}
void * thread_handler(void *arg)
{
printf("process id: %d thread id: %lu ", getpid(),pthread_self());
}
C. 一個進程最多可以創建多少個線程
1,在平台32位系統,系統佔用2GB地址空間,用戶方式2GB。如果使用VS,鏈接程序開關/SACK 或者/F可以設置線程堆棧大小,默認分配一個線程的堆棧大小是1MB,當CreateThread參數的StackSize大小與鏈接程序設置的不一致時,採用的方法是誰大用誰的,所以用4KB修改當然不會有改變!理論上最大線程數=2GB/1MB=2048。
實際上這個用戶方式的2GB並不會全部用作線程堆棧。首先程序的代碼和數據、進程環境塊、線程環境塊、空指針區域等等也需要佔用一定的地址空間;再者2GB只是虛擬內存,如果非分頁內存被用完,就無法再創建線程,這個與特定機器有關,所以不同機器上做最大線程數測試得到的數字可能不一樣。
2,操作系統給一個系統進程提供的空間是2GB ,而一個線程堆棧的空間默認在啟動的時候是1MB 那麼啟動完2000後,基本上就有2GB了,你可以減小默認堆棧的大小。
3,默認情況下,一個線程的棧要預留1M的內存空間而一個進程中可用的內存空間只有2G,所以理論上一個進程中最多可以開2048個線程
但是內存當然不可能完全拿來作線程的棧,所以實際數目要比這個值要小。你也可以通過連接時修改默認棧大小,將其改的比較小,這樣就可以多開一些線程。如將默認棧的大小改成512K,這樣理論上最多就可以開4096個線程。即使物理內存再大,一個進程中可以起的線程總要受到2GB這個內存空間的限制。比方說你的機器裝了64GB物理內存,但每個進程的內存空間還是4GB,其中用戶態可用的還是2GB。如果是同一台機器內的話,能起多少線程也是受內存限制的。每個線程對象都要站用非頁面內存,而非頁面內存也是有限的,當非頁面內存被耗盡時,也就無法創建線程了。
如果物理內存非常大,同一台機器內可以跑的線程數目的限制值會越來越大。
在Windows下寫個程序,一個進程Fork出2000個左右線程就會異常退出了,為什麼?
這個問題的產生是因為windows32位系統,一個進程所能使用的最大虛擬內存為2G,而一個線程的默認線程棧StackSize為1024K(1M),這樣當線程數量逼近2000時,2000*1024K=2G(大約),內存資源就相當於耗盡。
4,默認每線程1MB堆棧的話,只能開2048線程(如果你的其它系統資源足夠的話)。要想開更多線程,只能修改每個線程的堆棧,但實際中是不推薦這樣做的,因為如果你的線程因為一些工作因為線程堆棧不夠的話,會導致整個進程崩潰.修改堆棧的方法好像只在XP或以上系統有效,windows 2000中不支持。
D. linux怎樣在進程中創建線程
方法一:PS
在ps命令中,「-T」選項可以開啟線程查看。下面的命令列出了由進程號為<pid>的進程創回建的所有答線程。
$ ps -T -p <pid>
「SID」欄表示線程ID,而「CMD」欄則顯示了線程名稱。
方法二: Top
top命令可以實時顯示各個線程情況。要在top輸出中開啟線程查看,請調用top命令的「-H」選項,該選項會列出所有Linux線程。在top運行時,你也可以通過按「H」鍵將線程查看模式切換為開或關。
$ top -H
E. 一個進程可以創建多少個線程
一個進程可來以開啟的線程受可用內源存限制,如果是32位的機器,那麼默認一個進程有2G的可用內存,而每個線程默認分析1M的棧空間,所以這種情況下理論最線程數在2000多個。一個解決辦法是創建線程時減少線程棧的大小或是使用64位的系統。64位系統應該可以忽略這個問題了。當然受cpu及磁碟速度及物理內存的限制。不用到達上限值,你的機器應該已經是慢如牛車了。
F. 在一個線程中可以在創建線程或進程嗎
線程可以創建線程,像Java中,main函數就是一個線程來的,可以在main中創建線程。但是,線程應該不能創建進程。因為進程比線程要宏觀得多。
G. 線程中可以創建進程嗎
可以的 用fork()函數
H. Linux下查看某個進程創建了多少線程
$ ps -mp <PID>
例如查看mysqld進程中的線程
$ ps aux | grep mysqld
mysql 3496 0.7 51.7 4249652 2089140 ? Sl Dec05 10:42 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/data --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/lib/data/gk-compiler.err --pid-file=/var/lib/data/gk-compiler.pid --socket=/var/lib/mysql/mysql.sock --port=3306
從輸出結果可看出mysqld的PID是3496,繼續執行如下命令
$ ps -mp 3496
PID TTY TIME CMD
3496 ? 00:10:42 mysqld
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:00 -
- - 00:00:33 -
- - 00:00:00 -
- - 00:02:18 -
- - 00:01:42 -
- - 00:02:09 -
- - 00:01:48 -
- - 00:02:05 -
輸出的信息中「3496 ? 00:10:42 mysqld」這一行下面的都是該進程內的線程
I. 創建進程到底比線程多多少開銷
查看最大線程數:
cat /proc/sys/kernel/threads-max
ulimit
User limits - limit the use of system-wide resources.
Syntax
ulimit [-acdfHlmnpsStuv] [limit]
Options
-S Change and report the soft limit associated with a resource.
-H Change and report the hard limit associated with a resource.
-a All current limits are reported.
-c The maximum size of core files created.
-d The maximum size of a process's data segment.
-f The maximum size of files created by the shell(default option)
-l The maximum size that may be locked into memory.
-m The maximum resident set size.
-n The maximum number of open file descriptors.
-p The pipe buffer size.
-s The maximum stack size.
-t The maximum amount of cpu time in seconds.
-u The maximum number of processes available to a single user.
-v The maximum amount of virtual memory available to the process.
ulimit provides control over the resources available to the shell and to processes started by it, on systems that allow such control.
If limit is given, it is the new value of the specified resource. Otherwise, the current value of the soft limit for the specified resource is printed, unless the `-H' option is supplied.
When setting new limits, if neither `-H' nor `-S' is supplied, both the hard and soft limits are set.
Values are in 1024-byte increments, except for `-t', which is in seconds, `-p', which is in units of 512-byte blocks, and `-n' and `-u', which are unscaled values.
The return status is zero unless an invalid option is supplied, a non-numeric argument other than unlimited is supplied as a limit, or an error occurs while setting a new limit.
ulimit is a bash built in command.