使用计时器向阻塞的线程发送信号
sending signal to a blocked thread with a timer
我运行在同一个核心上安装了两个进程(进程 A 和 B)。进程 B 是多线程的,其中一个线程正在向下一个线程发送信号以唤醒它并开始其工作。同一时间进程B只有一个线程可以运行在common core上。
**//Process A**
#define _GNU_SOURCE
#include <sched.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
int main(int argc, char const *argv[])
{
struct timeval tval_result;
cpu_set_t my_set;
CPU_ZERO(&my_set);
CPU_SET(2, &my_set);
sched_setaffinity(0, sizeof(cpu_set_t), &my_set);
long int loopNum;
while(1)
{
gettimeofday(&tval_result, NULL);
printf("Dummy Time elapsed: %ld.%06ld\n", (long int)tval_result.tv_sec, (long int)tval_result.tv_usec);
//for(loopNum = 1; loopNum <= 100000; loopNum++);
//printf("Dummy!!! # \n");
}
return 0;
}
进程B的代码如下
//Import
#define _GNU_SOURCE
#include <sched.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#define NUM_THREADS 100
//global variables
pthread_cond_t condA[NUM_THREADS+1] = PTHREAD_COND_INITIALIZER;
pthread_cond_t condB = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_t tid[NUM_THREADS];
int state = 0;
void *threadA(void *data_)
{
int i = 0, rValue;
long int loopNum;
int turn = (intptr_t)data_;
struct timeval tval_result;
while(1)
{
cpu_set_t my_set;
CPU_ZERO(&my_set);
CPU_SET(2, &my_set);
sched_setaffinity(0, sizeof(cpu_set_t), &my_set);
/* Wait for state A */
pthread_mutex_lock(&mutex);
// while (state != STATE_A)
if(state != turn)
{
pthread_cond_wait(&condA[turn], &mutex);
}
pthread_mutex_unlock(&mutex);
//do stuff
gettimeofday(&tval_result, NULL);
printf("Time elapsed: %ld.%06ld\n", (long int)tval_result.tv_sec, (long int)tval_result.tv_usec);
//for(loopNum = 1; loopNum <= 10000000000; loopNum++);
//printf("Hello Thread # %d\n", turn);
/* Set state TRUE for next thread */
pthread_mutex_lock(&mutex);
state = (state +1)%NUM_THREADS;
pthread_cond_signal(&condA[state]);
pthread_mutex_unlock(&mutex);
}
}
int main(int argc, char *argv[])
{
int data = 0;
int err;
while(data < NUM_THREADS)
{
//create our threads
err = pthread_create(&tid[data], NULL, threadA, (void *)(intptr_t)data);
if(err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
else
printf("\n Thread created successfully\n");
data++;
}
pthread_exit(NULL);
}
我想在非常短的时间内(小于 1 微秒)在进程 A 的线程之间交错执行进程 B。因此,当进程 B 的线程 i 完成其工作时,它将向下一个线程 i+1 发送信号,在两者之间,我希望进程 A 来。这应该在执行过程的其余部分重复。
当我在 运行 上面的程序中运行时,进程 A 无法进入进程 B 的线程之间。有没有什么机制可以让我用一些定时器发送信号,这样信号就不会立即到达下一个线程(因此进程 A 在两个连续线程之间出现一段时间。)
您无法在该级别强制执行 Linux 调度程序。
您必须 "signal" 处理 A,然后让它 "signal" 另一个 B 线程。
但是 "signal" 可能是用户 space 机制,例如在共享内存中旋转变量。
我建议您首先尝试使用正常信号(通过内核),看看延迟是否足够好。只有太长了,才去玩转用户space.
不要期望所有这些都总是在 1us 下工作。无论旋转还是使用内核信号,您都可能会遇到很多抖动,必须将进程从该核心移开以减少它。
对于内核信号,您还可以使用套接字、管道、futexes...
现在我的问题是,如果您 运行 如您所说,将所有这些都集中在一个内核上,为什么不 运行 将其作为单个线程 - 只需让一个线程调用 B1,然后是 A,然后是 B2?
我运行在同一个核心上安装了两个进程(进程 A 和 B)。进程 B 是多线程的,其中一个线程正在向下一个线程发送信号以唤醒它并开始其工作。同一时间进程B只有一个线程可以运行在common core上。
**//Process A**
#define _GNU_SOURCE
#include <sched.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
int main(int argc, char const *argv[])
{
struct timeval tval_result;
cpu_set_t my_set;
CPU_ZERO(&my_set);
CPU_SET(2, &my_set);
sched_setaffinity(0, sizeof(cpu_set_t), &my_set);
long int loopNum;
while(1)
{
gettimeofday(&tval_result, NULL);
printf("Dummy Time elapsed: %ld.%06ld\n", (long int)tval_result.tv_sec, (long int)tval_result.tv_usec);
//for(loopNum = 1; loopNum <= 100000; loopNum++);
//printf("Dummy!!! # \n");
}
return 0;
}
进程B的代码如下
//Import
#define _GNU_SOURCE
#include <sched.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#define NUM_THREADS 100
//global variables
pthread_cond_t condA[NUM_THREADS+1] = PTHREAD_COND_INITIALIZER;
pthread_cond_t condB = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_t tid[NUM_THREADS];
int state = 0;
void *threadA(void *data_)
{
int i = 0, rValue;
long int loopNum;
int turn = (intptr_t)data_;
struct timeval tval_result;
while(1)
{
cpu_set_t my_set;
CPU_ZERO(&my_set);
CPU_SET(2, &my_set);
sched_setaffinity(0, sizeof(cpu_set_t), &my_set);
/* Wait for state A */
pthread_mutex_lock(&mutex);
// while (state != STATE_A)
if(state != turn)
{
pthread_cond_wait(&condA[turn], &mutex);
}
pthread_mutex_unlock(&mutex);
//do stuff
gettimeofday(&tval_result, NULL);
printf("Time elapsed: %ld.%06ld\n", (long int)tval_result.tv_sec, (long int)tval_result.tv_usec);
//for(loopNum = 1; loopNum <= 10000000000; loopNum++);
//printf("Hello Thread # %d\n", turn);
/* Set state TRUE for next thread */
pthread_mutex_lock(&mutex);
state = (state +1)%NUM_THREADS;
pthread_cond_signal(&condA[state]);
pthread_mutex_unlock(&mutex);
}
}
int main(int argc, char *argv[])
{
int data = 0;
int err;
while(data < NUM_THREADS)
{
//create our threads
err = pthread_create(&tid[data], NULL, threadA, (void *)(intptr_t)data);
if(err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
else
printf("\n Thread created successfully\n");
data++;
}
pthread_exit(NULL);
}
我想在非常短的时间内(小于 1 微秒)在进程 A 的线程之间交错执行进程 B。因此,当进程 B 的线程 i 完成其工作时,它将向下一个线程 i+1 发送信号,在两者之间,我希望进程 A 来。这应该在执行过程的其余部分重复。
当我在 运行 上面的程序中运行时,进程 A 无法进入进程 B 的线程之间。有没有什么机制可以让我用一些定时器发送信号,这样信号就不会立即到达下一个线程(因此进程 A 在两个连续线程之间出现一段时间。)
您无法在该级别强制执行 Linux 调度程序。 您必须 "signal" 处理 A,然后让它 "signal" 另一个 B 线程。
但是 "signal" 可能是用户 space 机制,例如在共享内存中旋转变量。
我建议您首先尝试使用正常信号(通过内核),看看延迟是否足够好。只有太长了,才去玩转用户space.
不要期望所有这些都总是在 1us 下工作。无论旋转还是使用内核信号,您都可能会遇到很多抖动,必须将进程从该核心移开以减少它。
对于内核信号,您还可以使用套接字、管道、futexes...
现在我的问题是,如果您 运行 如您所说,将所有这些都集中在一个内核上,为什么不 运行 将其作为单个线程 - 只需让一个线程调用 B1,然后是 A,然后是 B2?