当前位置:首页 » 操作系统 » linux定时线程

linux定时线程

发布时间: 2022-04-04 01:33:45

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什么时候调度线程

那情形可多了去了。

  1. 正常情况下,定时器中断到来的时候,如果当前进程时间片用尽,就要调度;

  2. 其他中断到来的时候,要进行调度,陷入内核;

  3. 进程主动要求调度的时候(如fork新线程、睡眠等等),要进行调度;

  4. 程序运行产生异常,无法继续运行,内核处理完异常恢复运行也要进行调度。

    还有其它各种情况,我一时也无法总结全,总之,内核“一言不和”就要进行调度……

热点内容
自己在家搭建服务器 发布:2024-11-15 04:25:04 浏览:648
箱娘免解压 发布:2024-11-15 04:24:58 浏览:38
热血宝宝脚本 发布:2024-11-15 04:23:31 浏览:225
正确的账号格式密码是什么样子的 发布:2024-11-15 04:18:41 浏览:24
可以升级方舟编译器的手机 发布:2024-11-15 04:18:39 浏览:694
地漏访问 发布:2024-11-15 04:08:13 浏览:388
朗逸豪华版wifi密码多少 发布:2024-11-15 04:03:09 浏览:664
安卓系统可安装什么电视直播软件 发布:2024-11-15 04:01:41 浏览:158
安卓如何开启蜂窝数据 发布:2024-11-15 03:19:59 浏览:887
androidedittext移动 发布:2024-11-15 03:14:28 浏览:471