使用计时器向阻塞的线程发送信号

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?