gpt4 book ai didi

c - 如何减少从 sem_wait 唤醒后的上下文切换时间

转载 作者:太空宇宙 更新时间:2023-11-04 04:38:27 26 4
gpt4 key购买 nike

我发现 sem_post 和 sem_wait 的时间间隔至少有 50 微秒。

sem_t gSema;
struct timeval gTv;

void *run(void *arg) {
int result;
struct timeval tv;
struct timespec nano = {0, 1};

while( 1 ) {
result = sem_trywait(&gSema);
if(result < 0) {
nanosleep(&nano, NULL);
continue;
}
if(result == 0) {
gettimeofday(&tv, NULL);
printf("waken up...elapsed time = %ld\n", (tv.tv_sec - gTv.tv_sec) * 1000000 + (tv.tv_usec - gTv.tv_usec));
}
}

return NULL;
}
void *run2(void *arg) {
int result;
struct timeval tv;

while( 1 ) {
result = sem_wait(&gSema);
if( result == 0 ) {
gettimeofday(&tv, NULL);
printf("waken up...elapsed time = %ld\n", (tv.tv_sec - gTv.tv_sec) * 1000000 + (tv.tv_usec - gTv.tv_usec));
}
}
return NULL;
}
int main(int argc, char **argv) {
pthread_t thr;
sem_init(&gSema, 0, 0);
pthread_create(&thr, NULL, run, NULL);

while( 1 ) {
sleep(1);
gettimeofday(&gTv, NULL);
sem_post(&gSema);
}
return 1;
}

首先,当我使用 run2() 运行代码时,运行时间为 50 微秒。然后 CPU 使用率很低。其次,当我在没有 nanosleep 的情况下使用 run() 运行代码时,运行时间为 0 或 1。但 CPU 使用率预计为 100%。使用 nanosleep,耗时为 1~50 微秒。

有没有更好的低 CPU 使用率和低延迟的方法?

最佳答案

使用 pthread_mutexpthread_cond 函数,我发现每个开关大约需要 4 微秒。下面的示例代码在大约 8 秒内循环了 100 万次(200 万个信号)。

#include <stdio.h>
#include <pthread.h>

#define LOOPS 1000000

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
int done = 0;

void *test( void *arg )
{
// lock the second mutex before signaling the parent,
// so that the parent cannot signal before the child is ready
pthread_mutex_lock( &mutex2 );

for (;;)
{
// signal the parent
pthread_mutex_lock( &mutex1 );
pthread_cond_signal( &cond1 );
pthread_mutex_unlock( &mutex1 );

// wait for the parent to signal back
pthread_cond_wait( &cond2, &mutex2 );

// check the done indicator, note that the done indicator is
// protected by the second mutex, which the child has locked
if ( done )
{
printf( "done\n" );
break;
}
}

// release the second mutex and exit
pthread_mutex_unlock( &mutex2 );
return NULL;
}

int main( void )
{
// lock the first mutex before launching the child,
// so that the child cannot signal before the parent is ready
pthread_mutex_lock( &mutex1 );

// launch the child thread
pthread_t child;
pthread_create( &child, NULL, test, NULL);

for ( int i = 0; i < LOOPS; i++ )
{
// give the user some feedback
if ( i % 100000 == 0 )
{
printf( "%7d\r", i );
fflush( stdout );
}

// wait for a signal from the child
pthread_cond_wait( &cond1, &mutex1 );

// lock the second mutex and signal the child,
// setting the done indicator if needed
pthread_mutex_lock( &mutex2 );
if ( i == LOOPS - 1 )
{
printf( "%7d\n", i + 1 );
done = 1;
}
pthread_cond_signal( &cond2 );
pthread_mutex_unlock( &mutex2 );
}

// release the first mutex, and wait for the child to finish
pthread_mutex_unlock( &mutex1 );
pthread_join( child, NULL );
}

关于c - 如何减少从 sem_wait 唤醒后的上下文切换时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28823810/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com