使用C+中的线程交替打印奇数和偶数+; 我遇到这个问题,想讨论C++中的解决方案。我能想到的是使用2个二进制信号量奇数和偶数信号量。偶数信号量初始化为1,奇数信号量初始化为0 **T1 thread function** funOdd() { wait(even) print odd; signal(odd) } **T2 thread function** funEven() { wait(odd) print even signal(even) }

使用C+中的线程交替打印奇数和偶数+; 我遇到这个问题,想讨论C++中的解决方案。我能想到的是使用2个二进制信号量奇数和偶数信号量。偶数信号量初始化为1,奇数信号量初始化为0 **T1 thread function** funOdd() { wait(even) print odd; signal(odd) } **T2 thread function** funEven() { wait(odd) print even signal(even) },c++,multithreading,thread-safety,semaphore,C++,Multithreading,Thread Safety,Semaphore,除此之外,如果我的函数只生成数字,并且有第三个线程T3将打印这些数字,那么理想的设计应该是什么?我使用了一个数组,其中奇数将放在奇数位置,偶数将放在偶数位置。T3将从此数组中读取,这将避免此数组上的任何线程安全,如果T3未找到任何索引,则将等待该索引被填充。另一种解决方案是使用一个队列,该队列将具有一个互斥量,在插入时T1和T2可以使用该互斥量 请评论此解决方案,以及如何使其更有效 编辑以使问题更加清楚:总体问题是我有两个生产者(T1、T2)和一个消费者(T3),我的生产者是相互依存的 我无法理

除此之外,如果我的函数只生成数字,并且有第三个线程T3将打印这些数字,那么理想的设计应该是什么?我使用了一个数组,其中奇数将放在奇数位置,偶数将放在偶数位置。T3将从此数组中读取,这将避免此数组上的任何线程安全,如果T3未找到任何索引,则将等待该索引被填充。另一种解决方案是使用一个队列,该队列将具有一个互斥量,在插入时T1和T2可以使用该互斥量

请评论此解决方案,以及如何使其更有效


编辑以使问题更加清楚:总体问题是我有两个生产者(T1、T2)和一个消费者(T3),我的生产者是相互依存的

我无法理解为什么要使用三个单独的线程进行串行行为。但我还是会回答:)

一种解决方案是使用改进的生产者/消费者模式,在生产者和消费者之间建立一个平衡。队列上的排序操作将取决于已发布消息的整数值。使用者将窥视队列中的一个元素,并检查它是否是下一个预期的元素。如果没有,它将休眠/等待

一段代码:

class Elt implements Comparable<Elt> {
  int value;
  Elt(value) { this.value=value; }
  int compare(Elt elt);
}

class EltQueue extends PriorityBlockingQueue<Elt> { // you shouldn't inherit colelctions, has-a is better, but to make it short
  static EltQueue getInstance(); // singleton pattern
}

class Consumer{
  Elt prevElt = new Elt(-1);
  void work()
  {
    Elt elt = EltQueue.getInstance().peek();
    if (elt.getValue() == prevElt.getValue()+1)) {
      EltQueue.getInstance().poll();
      //do work on Elt
    }
  }
}

class Producer {
  int n=0; // or 1!
  void work() {
    EltQueue.getInstance().put(new Elt(n+=2));
  }
}
类{
int值;
Elt(值){this.value=value;}
国际比较(英语教学);
}
类EltQueue扩展了PriorityBlockingQueue{//您不应该继承collections,has-a更好,但要使其简短
静态队列getInstance();//单例模式
}
阶级消费者{
Elt prevElt=新Elt(-1);
无效工作()
{
Elt=EltQueue.getInstance().peek();
如果(elt.getValue()==prevElt.getValue()+1)){
EltQueue.getInstance().poll();
//学习英语
}
}
}
阶级制作人{
int n=0;//或1!
无效工作(){
EltQueue.getInstance().put(新的Elt(n+=2));
}
}

首先,这两个函数至少应该包含一个循环(除非您只需要一个数字)

一个更标准的解决方案(重新映射您的想法)是使用一个全局结构,其中包含一个互斥体、两个条件变量(奇数和偶数)加上一个返回值,以及另一个打印条件。然后使用uique_锁来处理同步

在伪代码中:

struct global_t
{
    mutex mtx;
    int value = {0};
    condition_variable be_odd, be_even, print_it;
    bool bye = {false};

    global_t() { be_odd.notify(); }
} global;

void odd_generator()
{
    int my_odd = 1;
    for(;;)
    {
        unique_lock lock(global.mtx);
        if(global.bye) return;
        global.be_odd.wait(lock);
        global_value = my_odd; my_odd+=2;
        global.print_it.notify();
        if(my_odd > 100) bye=true;
    } //let RAII to manage wait states and unlocking
};

void even_generator()
{ /* same as odd, with inverted roles */ }

void printer()
{
    for(;;)
    {
        unique_lock lock(global.mtx);
        if(bye) return;
        global.ptint_it.wait(lock);
        std::cout << global.value << std::endl;
        ((global.value & 1)? global.be_even: global.be_odd).notify();
    }
}


int main()
{
    thread oddt(odd_generator), event(even_generator), printt(printer);
    oddt.join(), event.join(), printer.join();
}
struct全局
{
互斥mtx;
int值={0};
条件变量为奇数、偶数、打印;
bool bye={false};
全局_t(){be_odd.notify();}
}全球;
无效奇数_生成器()
{
int my_odd=1;
对于(;;)
{
唯一的锁(global.mtx);
if(global.bye)返回;
全局。奇怪。等待(锁定);
全局值=我的奇数;我的奇数+=2;
global.print_it.notify();
如果(我的奇数>100)bye=true;
}//让RAII管理等待状态和解锁
};
空偶发生器()
{/*与奇数相同,角色倒置*/}
作废打印机()
{
对于(;;)
{
唯一的锁(global.mtx);
如果(再见)返回;
global.ptint\u it.wait(锁);

标准::cout请参见以下工作代码(VS2005)

#包括
#包括
#包括
#包括
#定义最大值100
int共享_值=0;
临界截面;
未签名的标准调用偶数线程(void*p)
{
对于(int i=0;i
在这里,我们使用共享变量
shared\u value
,同步
偶数线程\u cs
奇数线程\u cs
。 请注意,不使用睡眠。

#包括
 #include  <stdio.h>
 #include  <stdlib.h>
 #include  <iostream>
 #include  <pthread.h>
 #include  <semaphore.h>

  sem_t sem;
  sem_t sem2;
  using namespace std ;

int count = 1;

void increment(int x)
{
    cout << "called by thread : " << x << "count is : " << count ++ << "\n";
}

void *printAltmessage1(void *thread_value)
{
    for(int m=0; m < (*(int *)thread_value); m++)
    {
        if (sem_wait(&sem) == 0)
        {
            cout << " Thread printAltmessage1 is executed" <<"\n";  
            increment(1);
            sem_post(&sem2);
        }
    }
}

void *printAltmessage2(void *thread_value)
{
    for(int m=0; m < (*(int *)thread_value); m++)
    {
        if (sem_wait(&sem2) == 0)
        {
            cout << " Thread printAltmessage2 is executed" <<"\n";
            increment(2);  
            sem_post(&sem);
        }
    }
}

int main()
{
     sem_init(&sem,0, 1);
     sem_init(&sem2,0, 0);
     pthread_t threads[2];
     int x =8;
     for(int i=0;i<2;i++)
     {
          if(i==0)
          int rc =pthread_create(&threads[i],NULL,printAltmessage1,(void*)&x);
          else
          int rc =pthread_create(&threads[i],NULL,printAltmessage2,(void*)&x);
      }
      pthread_exit(NULL);
      return 0;
}
#包括 #包括 #包括 #包括 扫描电镜; sem_t sem2; 使用名称空间std; 整数计数=1; 无效增量(整数x) {
cout解决方案基于C++11关键代码段aka

下面是工作代码,然后是解释

在VS2013上测试和工作:
使用名称空间std;
#包括
#包括
#包括
#包括
std::互斥mtx;
无效oddAndEven(整数n,整数结束);
int main()
{
标准:奇数螺纹(奇数,1,10);
标准:螺纹偶数(奥德丹文,2,10);
奇数连接();
偶数。join();
返回0;
}
无效ODANDEVEN(内部n,内部结束){
int x=n;
对于(;xstd::cout使用条件变量

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

std::mutex mu;
std::condition_variable cond;
int count = 1;

void PrintOdd()
{
    for(; count < 100;)
    {
        std::unique_lock<std::mutex> locker(mu);
        cond.wait(locker,[](){ return (count%2 == 1); });
        std::cout << "From Odd:    " << count << std::endl;
        count++;
        locker.unlock();
        cond.notify_all();
    }

}

void PrintEven()
{
    for(; count < 100;)
    {
        std::unique_lock<std::mutex> locker(mu);
        cond.wait(locker,[](){ return (count%2 == 0); });
        std::cout << "From Even: " << count << std::endl;
        count++;
        locker.unlock();
        cond.notify_all();
    }
}

int main()
{
    std::thread t1(PrintOdd);
    std::thread t2(PrintEven);
    t1.join();
    t2.join();
    return 0;
}
#包括
#包括
#包括
#包括
std::互斥mu;
std::条件变量cond;
整数计数=1;
void PrintOdd()
{
对于(;计数<100;)
{
标准:唯一的锁柜(mu);
cond.wait(locker,[](){返回(计数%2==1);});

std::cout这是您可以参考的最简单的解决方案:

#include<iostream>
#include<mutex>
#include<pthread.h>
#include<cstdlib>
int count=0;
using namespace std;
mutex m;
void* printEven(void *a)
{
   while(1)
   {
       m.lock();
       if(count%2==0)
       {
          cout<<" I am Even"<<count<<endl;
          count++;
       }
       if(count==100)
           break;
       m.unlock();
   }
}
void* printOdd(void *b)
{
    while(1)
    {
       m.lock();
       if(count%2!=0)
       {
           cout<<"I am odd"<<count<<endl;
           count++;
       }
       if(count>100)
          break;
       m.unlock();
    }
 }
 int main()
 {
     int *ptr = new int();
     pthread_t thread1, thread2;
     pthread_attr_t attr;
     pthread_attr_init(&attr);
     pthread_create(&thread1,&attr,&printEven,NULL);
     pthread_create(&thread2,&attr,&printOdd, NULL);
     pthread_join(thread1,&ptr);
     pthread_join(thread2,&ptr);
     delete ptr;
 }
#包括
#包括
#包括
#包括
整数计数=0;
使用名称空间std;
互斥m;
void*print偶数(void*a)
{
而(1)
{
m、 锁();
如果(计数%2==0)
{
不能包含
#包括
#包括
std::互斥mu;
无符号整数变化=0;
无效打印连续数(整数开始、整数结束、无符号整数连续)
{
int x=开始;
while(x#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex mu;
std::condition_variable cond;
int count = 1;

void PrintOdd()
{
    for(; count < 100;)
    {
        std::unique_lock<std::mutex> locker(mu);
        cond.wait(locker,[](){ return (count%2 == 1); });
        std::cout << "From Odd:    " << count << std::endl;
        count++;
        locker.unlock();
        cond.notify_all();
    }

}

void PrintEven()
{
    for(; count < 100;)
    {
        std::unique_lock<std::mutex> locker(mu);
        cond.wait(locker,[](){ return (count%2 == 0); });
        std::cout << "From Even: " << count << std::endl;
        count++;
        locker.unlock();
        cond.notify_all();
    }
}

int main()
{
    std::thread t1(PrintOdd);
    std::thread t2(PrintEven);
    t1.join();
    t2.join();
    return 0;
}
#include<iostream>
#include<mutex>
#include<pthread.h>
#include<cstdlib>
int count=0;
using namespace std;
mutex m;
void* printEven(void *a)
{
   while(1)
   {
       m.lock();
       if(count%2==0)
       {
          cout<<" I am Even"<<count<<endl;
          count++;
       }
       if(count==100)
           break;
       m.unlock();
   }
}
void* printOdd(void *b)
{
    while(1)
    {
       m.lock();
       if(count%2!=0)
       {
           cout<<"I am odd"<<count<<endl;
           count++;
       }
       if(count>100)
          break;
       m.unlock();
    }
 }
 int main()
 {
     int *ptr = new int();
     pthread_t thread1, thread2;
     pthread_attr_t attr;
     pthread_attr_init(&attr);
     pthread_create(&thread1,&attr,&printEven,NULL);
     pthread_create(&thread2,&attr,&printOdd, NULL);
     pthread_join(thread1,&ptr);
     pthread_join(thread2,&ptr);
     delete ptr;
 }
#include <iostream>
#include <thread>
#include <mutex>

std::mutex mu;
unsigned int change = 0;

void printConsecutiveNumbers(int start, int end,unsigned int consecutive)
{
    int x = start;
    while (x < end)
    {
        //each thread has check there time is coming or not
        if (change % consecutive == start)
        {
            std::unique_lock<std::mutex> locker(mu);
            std::cout << "Thread " << start << " -> " << x << std::endl;
            x += consecutive;
            change++;
            //to counter overflow
            change %= consecutive;
        }
    }
}

int main()
{
    //change num = 2 for printing odd and even
    const int num = 7;
    const int endValue = 1000;
    std::thread threads[num];
    //Create each consecutive threads
    for (int i = 0; i < num; i++)
    {
        threads[i] = std::thread(printConsecutiveNumbers, i, endValue, num);
    }

    //Joins all thread to the main thread
    for (int i = 0; i < num; i++)
    {
        threads[i].join();
    }

    return 0;
}
#include <iostream>
#include <thread>
#include <condition_variable>
using namespace std;

mutex mu;
condition_variable cond;
int count = 1;

void PrintOddAndEven(bool even, int n){
    while(count < n){
        unique_lock<mutex> lk(mu);
        cond.wait(lk, [&](){return count%2 == even;});
        cout << count++ << " ";
        lk.unlock();
        cond.notify_all();
    }
}

int main() {
    int n = 10;
    thread t1(PrintOddAndEven, true, n);
    thread t2(PrintOddAndEven, false, n);

    t1.join();
    t2.join();
    return 0;
}
#include<iostream>
#include<thread>
#include<mutex>
using namespace std;
mutex oddevenMu;
condition_variable condVar;
int number = 1;

void printEvenOdd(bool isEven, int maxnubmer)
{
    unique_lock<mutex> ul(oddevenMu);
    while (number < maxnubmer)
    {
        condVar.wait(ul, [&]() {return number % 2 == isEven;});
        cout << number++ << " ";
        condVar.notify_all();
    }

}

int main(string args[])
{
    thread oddThread(printEvenOdd, false, 100);
    thread evenThread(printEvenOdd, true, 100);
    oddThread.join();
    evenThread.join();
    return 0;
}