【问题标题】:How to pause execution between threads?如何暂停线程之间的执行?
【发布时间】:2012-08-19 15:38:17
【问题描述】:

我正在学习线程同步,这是一个演示如何在线程执行时锁定关键数据:

http://ideone.com/7Do0l (要运行此代码,请在 Linux/MacOS 环境下使用-pthread 参数编译它)

程序按预期运行,但sleep() 函数不会暂停线程之间的执行。我的想法是让一个线程一次进行计算,然后 1 秒后另一个线程开始发挥作用。这是我正在使用的代码段:

while(1) {
        //sleep(1);     //(1) (Sleep for one second)
        sem_wait(&mutex);
        //sleep(1);     //(2)
                printf("Thread #%d is doing math. %d + 1 = %d.\n", (int) id, s, s+1);
                s++;
        //sleep(1);     //(3)
        sem_post(&mutex);
        //sleep(1);     //(4)
}

我尝试将sleep() 放入四个位置。(1)和(4)导致单个线程之间没有停顿,但在两束十个线程之间。 (2) 和 (3) 导致一个线程在调用另一个线程之前重复执行很长时间。

有没有办法解决这个问题?

更新

有一个技巧可以让程序产生结果:为每个线程随机生成睡眠时间,但这并不一致,因为两个随机数可能偶然相同。

【问题讨论】:

  • 您到底想完成什么?您期望的行为是什么?
  • 应该是:Thread #1 is doing math. 1 + 1 = 2.(然后 1 秒后:)Thread #2 is doing math. 2 + 1 = 3.(等等)
  • 只有我一个人注意到这里的人们将 1 毫秒称为 1 秒,而答案将 100 毫秒以下称为 1 秒。
  • 不要调用信号量互斥体。
  • @Abhineet Linux 中的sleep() 函数以秒为单位,而Windows 中等效的Sleep()(大写S)以毫秒为单位。

标签: c multithreading pthreads


【解决方案1】:

我做了一些研究,发现产生所需输出的唯一方法是我在 更新 部分中提到的方法。也就是说,不用硬编码睡眠定时器,只需给每个线程一个随机数:

    // Sleep time in microseconds.
    int st = rand() % 500000;
    usleep(st);

实际上我一直在担心两个线程同时做同样的事情。即使两个相邻的随机计时器可能意外相同,两个线程也不会同时在 CPU 的同一个内核上执行,如果 CPU 是多个内核,则没有两条指令可以同时修改相同的内存内容。

【讨论】:

    【解决方案2】:

    这并不是线程旨在解决的真正问题。您必须为每个线程有一个单独的信号量,让一个线程循环通过这些信号量,每秒在不同的信号量上调用 sem_post,其余的只调用 sem_wait。也可以只使用一个线程。

    【讨论】:

    • 我相信有一个解决方案,因为这个小程序是我下一个作业要做的原型。我必须设法让数百个类似的线程轮流执行它们的部分,只使用几个信号量来控制。
    【解决方案3】:

    将它放在第三位,因为您希望在 printf 消息之间延迟一秒。

    如果要确保所有线程在进入临界区之前都已初始化,请将链接代码的main函数修改为此

    int main() {
        pthread_t thread[10];
    
        int i;
        sem_init(&mutex, 0, 1);
        sem_wait(&mutex);
        for (i = 0; i<10; ++i)
                pthread_create(&(thread[i]), NULL, job, (void*) i);
        sem_post(&mutex);
        sleep(100);
    }
    

    【讨论】:

    • 我尝试了很多次,(2)和(3)导致相同的行为:一个线程被重复执行。
    • 那么你期望的输出是什么?
    • 感谢您的代码,我刚刚尝试过,但它的工作方式完全相同。你会看到整个十个线程同时执行,然后是暂停,然后是另外一堆十个线程......至于预期的输出,我已经在上面说清楚了两次......
    • 把它放在第三个位置会产生你描述的输出:Thread #1 is doing math. 1 + 1 = 2., (1s delay), Thread #2 is doing math. 2 + 1 = 3., (1s delay), Thread #3 is doing math. 3 + 1 = 4. etc.
    • 这是我的电脑生成的结果,使用Linux,将main()函数替换为你的,sleep()函数在第三位:Thread #1 is doing math. 0 + 1 = 1. Thread #1 is doing math. 1 + 1 = 2. Thread #1 is doing math. 2 + 1 = 3. Thread #1 is doing math. 3 + 1 = 4.等等......我的之前的评论是错误的:在 (2) 和 (3) 位置,sleep() 导致一个线程被重复执行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    • 2015-11-05
    • 1970-01-01
    相关资源
    最近更新 更多