linux定時線程
A. linux線程如何運行
pthread_create執行後,如果執行成功會生成一個子線程 也就是現在有兩個線程同時運行
父線程還會繼續執行後面的代碼 直到結束
子線程則開始執行thread函數體里的代碼了 別的不執行
pthread_join會按照父線程執行順序 到它了就會執行 該函數的作用是阻塞等待一個線程執行完畢
在你的代碼里 不一定在子線程執行3次後才啟動 也可能子線程沒有執行呢 父線程就執行到pthread_join了 然後阻塞等待子線程
如果你想讓pthread_join在子線程3次執行後才啟動 可以讓父線程sleep下 不過子線程執行完了 你再執行pthread_join也就沒有什麼意義了
不懂再問
B. linux alarm 能在線程中用嗎
不管是在進程還是線程,很多時候我們都會使用一些定時器之類的功能,這里就定時器在多線程的使用說一下。首先在linux編程中定時器函數有alarm()和setitimer(),alarm()可以提供一個基於秒的定時功能,而setitimer可以提供一個基於微妙的定時功能。
alarm()原型:
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
這個函數在使用上很簡單,第一次調用這個函數的時候是設置定時器的初值,下一次調用是重新設置這個值,並會返回上一次定時的剩餘時間。
setitimer()原型:
#include <sys/time.h>
int setitimer(int which, const struct itimerval *value,struct itimerval *ovalue);
這個函數使用起來稍微有點說法,首先是第一個參數which的值,這個參數設置timer的計時策略,which有三種狀態分別是:
ITIMER_REAL:使用系統時間來計數,時間為0時發出SIGALRM信號,這種定時能夠得到一個精準的定時,當然這個定時是相對的,因為到了微秒級別我們的處理器本身就不夠精確。
ITIMER_VIRTUAL:使用進程時間也就是進程分配到的時間片的時間來計數,時間為0是發出SIGVTALRM信號,這種定時顯然不夠准確,因為系統給進程分配時間片不由我們控制。
ITIMER_PROF:上面兩種情況都能夠觸發
第二個參數參數value涉及到兩個結構體:
struct itimerval {
struct timeval it_interval; /* next value */
struct timeval it_value; /* current value */
};
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
在結構體itimerval中it_value是定時器當前的值,it_interval是當it_value的為0後重新填充的值。而timeval結構體中的兩個變數就簡單了一個是秒一個是微秒。
上面是這兩個定時函數的說明,這個函數使用本不是很難,可以說是很簡單,但是碰到具體的應用的時候可能就遇到問題了,在多進程編程中使用一般不會碰到什麼問題,這里說的這些問題主要體現在多線程編程中。比如下面這個程序:
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
void sig_handler(int signo)
{
alarm(2);
printf("alarm signal\n");
}
void *pthread_func()
{
alarm(2);
while(1)
{
pause();
}
}
int main(int argc, char **argv)
{
pthread_t tid;
int retval;
signal(SIGALRM, sig_handler);
if((retval = pthread_create(&tid, NULL, pthread_func, NULL)) < 0)
{
perror("pthread_create");
exit(-1);
}
while(1)
{
printf("main thread\n");
sleep(10);
}
return 0;
}
這個程序的理想結果是:
main thread
alarm signal
alarm signal
alarm signal
alarm signal
alarm signal
main thread
可事實上並不是這樣的,它的結果是:
main pthread
alarm signal
main pthread
alarm signal
main pthread
為什麼會出現這種情況呢?是因為發送給工作線程的信號中斷的主線程的sleep,並且這個中情況隻影響主線程而不會影響到其他的工作線程。我們怎麼才能解決這種問題呢,最簡單的方法是修改這個程序,修改這個線程主線程使用alarm,工作線程使用sleep。這樣就能夠達到我們的要求,但是有時候有不能簡單的這樣操作。所以我們就需要進一步的修改我們的程序。在這里我第一個想到的是使用signal(SIGALRM, SIG_IGN),可是這個是設置整個進程對這個信號的響應方式,經過測試也確實不能完成我期望的功能,那麼怎麼辦呢?有這樣一個函數pthread_sigmask,線程中的信號屏蔽,函數的原型及相關函數為:
#include <signal.h>
int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);
函數中第一個參數how有三個值SIG_BLOCK、SIG_SETMASK和SIG_UNBLOCK這里我們是用第二個值SIG_SETMASK
int sigemptyset(sigset_t *set); /*清除信號集合set*/
int sigaddset(sigset_t *set, int signum); /*添加信號signum到信號集set中*/
然後我們改造我們的程序為:
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
void sig_handler(int signo)
{
alarm(2);
printf("alarm signal\n");
}
void *pthread_func()
{
alarm(2);
while(1)
{
pause();
}
}
int main(int argc, char **argv)
{
pthread_t tid, tid_1;
int retval;
signal(SIGALRM, sig_handler);
if((retval = pthread_create(&tid, NULL, pthread_func, NULL)) < 0)
{
perror("pthread_create");
exit(-1);
}
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGALRM);
pthread_sigmask(SIG_SETMASK,&sigset,NULL);
while(1)
{
printf("main pthread\n");
sleep(10);
}
return 0;
}
這個時候我們就能夠看到我們想要的結果了。
這里再附一個setitimer的使用範例:
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
struct itimerval timerval;
void sig_handler(int signo)
{
printf("alarm signal\n");
}
void *pthread_func()
{
setitimer(ITIMER_REAL, &timerval, NULL);
while(1)
{
pause();
}
}
int main(int argc, char **argv)
{
pthread_t tid;
int retval;
timerval.it_interval.tv_sec = 2;
timerval.it_interval.tv_usec = 0;
timerval.it_value.tv_sec = 2;
timerval.it_value.tv_usec = 0;
signal(SIGALRM, sig_handler);
if((retval = pthread_create(&tid, NULL, pthread_func, NULL)) < 0)
{
perror("pthread_create");
exit(-1);
}
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGALRM);
pthread_sigmask(SIG_SETMASK,&sigset,NULL);
while(1)
{
printf("main thread\n");
sleep(5);
}
return 0;
}
C. linux下怎麼實現線程的定時搶占
進程優先順序別,貌似有個命令
D. Redhat Linux中怎樣自動設置線程堆棧大小
不是可以直接用線程屬性進行設置嗎?
我寫了一個小程序。如下:
#include <pthread.h>
#include <limits.h>#define Thread_NUM 5void *MultiThread_soap_serve(){ sleep(5); printf("new pthread!!\n");}//PTHREAD_STACK_MIN 經過計算是16K。//64*16K = 1M,線程堆棧應該是夠用的。#define MICHAEL_SET_PTHREAD_STACK_SIZE 64int main(){ pthread_attr_t attr; pthread_attr_init(&attr); size_t stacksize = MICHAEL_SET_PTHREAD_STACK_SIZE*PTHREAD_STACK_MIN; //stacksize =PTHREAD_STACK_MIN; //stackaddr=(void*)malloc((N+1)*PTHREAD_STACK_MIN); //pthread_attr_getstack(&attr,&statckattr,&stacksize); //pthread_attr_setstack(&attr,stackaddr,); pthread_attr_setstacksize(&attr,stacksize); int iThreadNum = 0; pthread_t PSoapThread[Thread_NUM]; for ( ; iThreadNum < Thread_NUM ; iThreadNum++ ) { pthread_create(&PSoapThread[iThreadNum],&attr,MultiThread_soap_serve,(void *)NULL); } pthread_attr_destroy(&attr); while(1) { sleep(10); printf("main!!\n"); }}
E. linux中我想用jstack捕獲java線程,捕獲10次,每隔5秒捕獲一次並把捕獲的生成文件,然後生成壓縮包文件
sh腳本,加上定時任務
F. linux內核進行線程切換需要多少時間
Linux內核切換線程時間在微秒級別,幾十微秒。
1. 查看需要更新的內核命令:
apt-cachesearchlinux
#該命令將會顯示所有可以獲取的內核
2. 安裝內核,假設要安裝的內核為2.6.39-0,則使用下面的命令
sudoapt-getinstalllinux-headers-2.6.39-0-genericlinux-image-2.6.39-0-generic
#安裝後,reboot即可,重啟後,既是以新內核啟動。
G. 在linux環境中,如何實現多線程中使用多個定時器,POSIX定時器可以嗎,如何用
個人解決了,以下是一個實現:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#if 1
pthread_attr_t attr;
timer_t hard_timer, software_timer;
struct sigevent hard_evp, software_evp;
static void watchdog_hard_timeout(union sigval v)
{
time_t t;
char p[32];
timer_t *q;
struct itimerspec ts;
int ret;
time(&t);
strftime(p, sizeof(p), "%T", localtime(&t));
printf("watchdog hard timeout!\n");
printf("%s thread %d, val = %u, signal captured.\n", p, (unsigned int)pthread_self(), v.sival_int);
q = (timer_t *)(v.sival_ptr);
printf("hard timer_t:%d add:%p, q:%p!\n", (int)hard_timer, &hard_timer, q);
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
ts.it_value.tv_sec = 6;
ts.it_value.tv_nsec = 0;
ret = timer_settime(*q, CLOCK_REALTIME, &ts, NULL);
if (ret != 0) {
printf("settime err(%d)!\n", ret);
}
}
static void watchdog_software_timeout(union sigval v)
{
time_t t;
char p[32];
timer_t *q;
struct itimerspec ts;
int ret;
time(&t);
strftime(p, sizeof(p), "%T", localtime(&t));
printf("watchdog software timeout!\n");
printf("%s thread %d, val = %u, signal captured.\n", p, (unsigned int)pthread_self(), v.sival_int);
q = (timer_t *)(v.sival_ptr);
printf("hard timer_t:%d add:%p, q:%p!\n", (int)hard_timer, &hard_timer, q);
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
ts.it_value.tv_sec = 10;
ts.it_value.tv_nsec = 0;
ret = timer_settime(*q, CLOCK_REALTIME, &ts, NULL);
if (ret != 0) {
printf("settime err(%d)!\n", ret);
}
}
static void dcmi_sol_pthread_attr_destroy(pthread_attr_t *attr)
{
pthread_attr_destroy(attr);
}
static int dcmi_sol_pthread_attr_init(pthread_attr_t *attr)
{
int ret;
if ((ret = pthread_attr_init(attr) != 0)) {
goto err;
}
if ((ret = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)) != 0) {
dcmi_sol_pthread_attr_destroy(attr);
goto err;
}
/* 設置線程的棧大小,失敗則用系統默認值 */
pthread_attr_setstacksize(attr, 128 * 1024);
return 0;
err:
printf("set ptread attr failed(ret:%d)!\n", ret);
return -1;
}
int main(void)
{
struct itimerspec ts;
int ret;
ret = dcmi_sol_pthread_attr_init(&attr);
if (ret != 0) {
printf("init pthread attributes fail(%d)!\n", ret);
exit(-1);
}
memset(&hard_evp, 0, sizeof(struct sigevent));
hard_evp.sigev_value.sival_ptr = &hard_timer;
hard_evp.sigev_notify = SIGEV_THREAD;
hard_evp.sigev_notify_function = watchdog_hard_timeout;
hard_evp.sigev_notify_attributes = NULL;//&attr;
memset(&software_evp, 0, sizeof(struct sigevent));
software_evp.sigev_value.sival_ptr = &software_timer;
software_evp.sigev_notify = SIGEV_THREAD;
software_evp.sigev_notify_function = watchdog_software_timeout;
software_evp.sigev_notify_attributes = NULL;//&attr;
ret = timer_create(CLOCK_REALTIME, &hard_evp, &hard_timer);
if(ret != 0) {
perror("hard timer_create fail!");
exit(-1);
}
ret = timer_create(CLOCK_REALTIME, &software_evp, &software_timer);
if (ret != 0) {
timer_delete(hard_timer);
perror("software timer_create fail!");
exit(-1);
}
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
ts.it_value.tv_sec = 6;
ts.it_value.tv_nsec = 0;
ret = timer_settime(hard_timer, CLOCK_REALTIME, &ts, NULL);
if(ret != 0) {
perror("hard timer_settime fail!");
timer_delete(hard_timer);
timer_delete(software_timer);
exit(-1);
}
ts.it_value.tv_sec = 10;
ret = timer_settime(software_timer, CLOCK_REALTIME, &ts, NULL);
if(ret != 0) {
perror("hard timer_settime fail!");
timer_delete(hard_timer);
timer_delete(software_timer);
exit(-1);
}
while(1) {
printf("main ready sleep!\n");
sleep(15);
printf("main sleep finish!\n");
}
return 0;
}
#endif
H. linux下main()中新建一個線程,延時問題
你對sleep可能有些誤解,sleep本身就是使進程睡眠,睡眠的線程不會去佔用CPU的。對於一個正在運行的線程來說,他最主要佔用的資源就是CPU運行時間和內存。既然SLEEP使其放棄對CPU的進程許可權(意思是這段時間內,他不會到CPU執行,如果想了解原因和具體實現可以參考linux內核代碼對sleep的實現),那你不想讓他佔用資源意思就是說:不想讓它占內存嘍??
從定義角度來說,線程不擁有內存資源(從內核中可以查到fork和vfork創建的都是線程,他們都不會新分配內存空間,而是和父進程共享內存空間),所以說你已經沒有什麼可以釋放了。如果還不明白,可以發信息給我。
或許你更希望做的是,壓根就不啟動這個線程,而是一個小時後啟動。因為你沒有辦法然main主線程1小時後啟動這個線程,因為你把握不好時間,那我可以建議你考慮下linux守護線程cron,這個可以達到你1小時後啟動的目的。
I. linux如何進行線程管理
方法一:PS
在ps命令中,「-T」選項可以開啟線程查看。下面的命令列出了由進程號為<pid>的進程創建的所有線程。
1.$ ps -T -p <pid>
「SID」欄表示線程ID,而「CMD」欄則顯示了線程名稱。
方法二: Top
top命令可以實時顯示各個線程情況。要在top輸出中開啟線程查看,請調用top命令的「-H」選項,該選項會列出所有Linux線程。在top運行時,你也可以通過按「H」鍵將線程查看模式切換為開或關。
1.$ top -H
要讓top輸出某個特定進程<pid>並檢查該進程內運行的線程狀況:
$ top -H -p <pid>
J. linux什麼時候調度線程
那情形可多了去了。
正常情況下,定時器中斷到來的時候,如果當前進程時間片用盡,就要調度;
其他中斷到來的時候,要進行調度,陷入內核;
進程主動要求調度的時候(如fork新線程、睡眠等等),要進行調度;
程序運行產生異常,無法繼續運行,內核處理完異常恢復運行也要進行調度。
還有其它各種情況,我一時也無法總結全,總之,內核「一言不和」就要進行調度……