c - 了解并行线程执行

标签 c multithreading pthreads

编写简单的 C 代码,试图控制来自两个不同线程的输出:

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

sem_t sem;

void* thread_func(void* aArgs)
{
  printf("Entering thread %p with %d\n", (void*)pthread_self(), (int)aArgs);
  int i = 0;
  for(;i < 10; i++)
  {
    sem_wait(&sem);
    if ((i % 2) == (int)aArgs)
      printf("val is %d in thread %p \n", i, (void*)pthread_self());
    sem_post(&sem);
  }
}

int main()
{
  pthread_t thread_1, thread_2;

  sem_init(&sem, 0, 1);

  pthread_create(&thread_1, NULL, (void*)thread_func, (void*)0);
  pthread_create(&thread_2, NULL, (void*)thread_func, (void*)1);

  pthread_join(thread_1, NULL);
  pthread_join(thread_2, NULL);

  sem_destroy(&sem);

  return 0;
}

我想要实现的是混合奇数和偶数的序列。但是我从一个线程收到所有数字,然后从第二个线程收到所有其他数字,就像这样(即使我增加了循环计数器的大小):

Entering thread 0xb75f2b40 with 0
val is 0 in thread 0xb75f2b40 
val is 2 in thread 0xb75f2b40 
val is 4 in thread 0xb75f2b40 
val is 6 in thread 0xb75f2b40 
val is 8 in thread 0xb75f2b40 
Entering thread 0xb6df1b40 with 1
val is 1 in thread 0xb6df1b40 
val is 3 in thread 0xb6df1b40 
val is 5 in thread 0xb6df1b40 
val is 7 in thread 0xb6df1b40 
val is 9 in thread 0xb6df1b40

问题是为什么两个独立的线程表现得像两个顺序任务?为什么第二个线程直到第一个线程还没有完成所有的事情才取得执行控制权?

我尝试将 pthread_yield() 添加到 for 循环的末尾,但情况并没有发生显着变化:有时我得到预期的输出,有时 - 如上所述。

更新。我怎样才能实现确定性的一对一线程执行?是否有任何同步原语?

最佳答案

如果你想得到想要的输出,你应该使用两个信号量而不是一个。每个线程都应该等待自己的信号量,并在每次循环迭代完成后发布另一个线程的信号量。主线程可以创建一个值为 1 的信号量和另一个值为零的信号量以正确开始。这将强制两个线程以交替顺序运行。

由于程序是当前编写的,执行 sem_post 后跟 sem_wait 可能会导致同一个线程立即获取信号量(在单 cpu 系统上) ).我很惊讶 pthread_yield 没有帮助,但无论如何使用两个信号量将保证正确的顺序。

关于c - 了解并行线程执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28663965/

相关文章:

java - 从 native 代码分派(dispatch)的 pthread 可以回调到 JNI 吗?

c - 实现生产者/消费者沟通

c++ - 如何将长值转换为字符串而不改变其内容?

C - 初始化结构成员 - 指针数组。第二个元素的值不正确

c# - 无法在单元测试中复制 'cross-thread operation not valid' 错误 - 我不明白

c# - 如何正确阻止方法直到对象计数器> 0?

c++ - 在 C++ 中使用 pthread 时出现编译错误

c++ - 奇怪的线程执行顺序?

c - C 上的 float 问题

c - Nginx 模块用于从 MongoDB 的 Make 错误中提供文件