编写简单的 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/