gpt4 book ai didi

c++ - 使用 sched_yield 控制线程执行

转载 作者:行者123 更新时间:2023-11-28 05:59:51 26 4
gpt4 key购买 nike

我有 2 个线程:将“重新打印”用户输入语句的元音和辅音。元音线程将打印以元音开头的单词,辅音线程将打印以辅音开头的单词...我正在尝试使用 sched_yield() 使输出与用户输入的顺序相同...所以如果用户输入是:大家好,辅音线程将打印 hi 和元音将打印所有,按该顺序..但似乎我遗漏了一些东西,因为我没有得到相同的顺序..你能帮忙......

void *vowels( void *s )
{
for(int i = 1; i < noOfTokens; i++){
string str = tokens[i];
size_t found = str.find_first_of(vowelList);
if(found == 0){
printf("vows %s\n", tokens[i]);
}
else {
sched_yield();
}
}
pthread_exit(0);
}


/* the cons thread should print all words starting with a consonant. */
void *consonants( void *s )
{
for(int j = 1; j < noOfTokens; j++){
string str = tokens[j];
size_t found = str.find_first_of(vowelList);
if(found != 0){
printf("cons %s\n", tokens[j]);
}
else {
sched_yield();
}
}
pthread_exit(0);

}

最佳答案

正如 Kenney 所说,单独使用 yield 不会帮助您同步这两个线程。为此,您必须使用互斥锁或其他一些同步原语。话虽如此,我还是忍不住注意到您的问题可以借助 条件变量 优雅地解决。我选择使用 c++11std::thread,以及 std::mutexstd::condition_variable.

我稍微简化了您的问题,我的目标是打印偶数和奇数整数按照输入的顺序购买两个不同的线程(一个线程负责偶数,另一个线程负责奇数)。一种可能的解决方案可能是:

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex m;
std::condition_variable cv;
unsigned int index = 0;

void ProcessEvenNumbers(void *p_array)
{
std::vector<int>& buffer(*reinterpret_cast<std::vector<int>*>(p_array));
std::unique_lock<std::mutex> lock(m);

while (index < buffer.size())
{
if (buffer[index] % 2 == 0)
{
std::cout << "thread_1: " << buffer[index] << std::endl;
++index;
}
else
{
cv.wait(lock);
}
}
}

void ProcessOddNumbers(void *p_array)
{
std::vector<int>& buffer(*reinterpret_cast<std::vector<int>*>(p_array));
std::unique_lock<std::mutex> lock(m);

while(index < buffer.size())
{
if (buffer[index] % 2 != 0)
{
std::cout << "thread_2: " << buffer[index] << std::endl;
++index;
}
else
{
lock.unlock();
cv.notify_one();
std::this_thread::sleep_for(std::chrono::microseconds(1));
lock.lock();
}
}

cv.notify_one();
}

int main()
{
std::vector<int> buffer{ 1, 3, 24, 5, 100, -23, -2, -2, 7, 9, 11, 13, 15, 17, 2, 4, 6, 8, 10, 12, 14 };
std::thread thread_2(ProcessOddNumbers, &buffer);
std::thread thread_1(ProcessEvenNumbers, &buffer);

thread_1.join();
thread_2.join();

return 0;
}

处理偶数的线程(ProcessEvenNumbers())在遇到奇数时使用条件变量阻塞自己。处理奇数的线程 (ProcessOddNumbers()) 使用 notify_one() 在遇到偶数时解锁另一个线程,并通过尝试重新锁定互斥量(此时已被其他线程锁定)。

std::this_thread::sleep_for() 很关键,因为它强制进行上下文切换,允许 thread_1thread_2 之后锁定互斥量向条件变量发出信号。

P.S. 线程的运行顺序无关紧要。

关于c++ - 使用 sched_yield 控制线程执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33487785/

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