【问题标题】:How to forcefully make one thread to be executed first in c如何强制使一个线程在c中首先执行
【发布时间】:2021-01-28 02:22:40
【问题描述】:

我在 c 中创建了两个线程。我想通过每个线程执行两个单独的函数。如何让一个特定的线程首先被执行。

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

void* function_1(void* p)
{
   // statements
}

void* function_2(void* p)
{
   // statements
}

int main(void)
{
   pthread_t id1;
   pthread_t id2;

   pthread_create(&id1, NULL, function_1, NULL);
   pthread_create(&id2, NULL, function_2, NULL);
   pthread_exit(NULL);
}

程序启动时如何让function_1在function_2之前执行?

【问题讨论】:

  • 是否值得在多线程程序中要求顺序执行?最好让一个单线程程序顺序调用这两个函数。
  • 如果你真的需要同步线程,你可以使用一个pthreads condition variable和一个pthreads mutex

标签: c linux multithreading pthreads


【解决方案1】:

如其他答案之一所述,您的问题可能是XY problem。在这种情况下,最好不要使用多线程,而是使用单线程。

如果您确实想使用线程,那么正如其他答案之一中所述,使用 pthread_join 可能是您在问题中发布的代码的最佳解决方案。

然而,如果你只是想确保function_2中的代码在另一个线程执行完function_1之前不会被执行,并且不想等待执行function_1的线程终止(例如因为该线程应该在调用function_1 后执行其他操作),那么我建议您使用pthreads condition variable 和pthreads mutex 同步线程。

以下示例将代码添加到function_1 的末尾,以通知另一个线程它现在可以继续使用function_2。它还将代码添加到 function_2 的开头,等待发送此信号。

示例如下:

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

struct sync_data
{
    pthread_mutex_t mutex;
    volatile int predicate;
    pthread_cond_t cond;
};

void* function_1(void* p)
{
    // the function's main code goes here

    //signal to other thread that it may now proceed
    struct sync_data *psd = p;
    pthread_mutex_lock( &psd->mutex );
    psd->predicate = 1;
    pthread_mutex_unlock( &psd->mutex );
    pthread_cond_signal( &psd->cond );
}

void* function_2(void* p)
{
    //wait for signal from other thread
    struct sync_data *psd = p;
    pthread_mutex_lock( &psd->mutex );
    while ( !psd->predicate )
        pthread_cond_wait( &psd->cond, &psd->mutex );
    pthread_mutex_unlock( &psd->mutex );

    // the function's main code goes here
}

int main(void)
{
    struct sync_data sd;
    pthread_t id1;
    pthread_t id2;

    //init sync_data struct members
    pthread_mutex_init( &sd.mutex, NULL );
    sd.predicate = 0;
    pthread_cond_init( &sd.cond, NULL );

    //create and start both threads
    pthread_create( &id1, NULL, function_1, &sd );
    pthread_create( &id2, NULL, function_2, &sd );

    //wait for all threads to finish
    pthread_join(id1, NULL);
    pthread_join(id2, NULL);

    //cleanup
    pthread_mutex_destroy( &sd.mutex );
    pthread_cond_destroy( &sd.cond );
}

【讨论】:

  • 不错,但“谓词”是一个布尔变量的有趣名称。 “谓词”听起来像一个计算布尔值的函数。许多程序员会将该变量称为flag。有些人可能会称之为safe_for_func2_to_gofunc1_has_done_its_dirty_work
  • @SolomonSlow:我称它为“谓词”,因为它是条件变量的谓词。 Every condition variable has a predicate。没错,在具有多个谓词变量的大型程序中,不要简单地将谓词变量命名为predicate,而是一个更具描述性的名称,例如safe_for_func2_to_go,这样会更有意义。然而,在这个简单的案例中,它似乎适合我。
【解决方案2】:

@SolomonSlow 已经说明了这一点。如果要顺序执行,为什么要有多个线程?

只是为了完整性:

pthread_create(&id1, NULL, function_1, NULL);
pthread_join(id1, NULL);
pthread_create(&id2, NULL, function_2, NULL);

【讨论】:

    【解决方案3】:

    将你的 main 函数改成如下所示:

    int main(void) {
        function_1(NULL);
        function_2(NULL);
    }
    

    不开玩笑!如果在function_1() 完成之前不开始function_2() 很重要,那么就是这样做的。任何时候你需要一个程序以某种严格的顺序来做某些事情;实现这一目标的最佳方法是在同一个线程中完成所有事情。

    线程确实需要不时地相互“同步”(例如,消费者在生产者放入某些东西之前从队列中取出某些东西是没有任何意义的进入队列),但如果您的线程没有花费 大部分 时间彼此独立 工作,那么您可能不会获得任何好处避免使用多个线程。

    【讨论】:

      猜你喜欢
      • 2012-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-26
      • 2016-08-27
      • 1970-01-01
      相关资源
      最近更新 更多