我的代码有问题。它有效,但是我无法避免使用全局信号量。我有3个线程功能。第一个由10个线程运行。第二个和第三个分别由2个线程运行。这些线程应在没有竞争条件的情况下运行。另外,他们应该互相沟通。我使用用户定义的队列类在线程之间以及线程和main之间进行通信。另外,我使用信号量实现线程之间的互斥。由于我以全局方式声明了队列类和信号量的实例,因此我不必将它们传递给任何函数。这些程序中的任何功能都可以访问它们。但是,这不是编写程序的健康方法。因此,我问你,如何在本地声明队列和信号量,以及在线程之间传递它们的最佳方法是什么。
// queueString标头
#include <string>
#include <queue>
#include <semaphore.h>
using namespace std;
class queueString
{
public:
queueString();
~queueString();
void qPush(string str);
string qPop();
private:
sem_t queueSem;
queue <string> q;
};
// queueString类
#include "queueString.h"
using namespace std;
// queue class that will enqueue and dequeue atomically.
queueString::queueString(){
sem_init(&queueSem, 0, 1);
}
queueString::~queueString(){}
void queueString::qPush(string str){
sem_wait(&queueSem);
this->q.push(str);
sem_post(&queueSem);
}
string queueString::qPop(){
sem_wait(&queueSem);
string str = this->q.front();
q.pop();
sem_post(&queueSem);
return str;
}
//具有主线程的三个线程
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <iostream>
#include "queueString.h"
using namespace std;
//My question is here, How to declare the variables below locally, and where
// is the right place to declare them, and how to pass them to threads?
sem_t s12, s13, s21, s31, sthr1, sthr2[2], sthr3[2], printSem;
sem_t idInitializationSemMainToThread, idInitializationSemThreadToMain;
queueString q = queueString();
#define THR1NUM 10
#define THR2NUM 2
#define THR3NUM 2
void printString(string str);
void *thread1(void* arg){
sem_wait(&idInitializationSemMainToThread);
int *pnum = (int *)arg;
int thr_1_ID = *pnum;
sem_post(&idInitializationSemThreadToMain);
sem_wait(&sthr1);
string value= "THR1 ";
value.append(to_string(thr_1_ID));
q.qPush(value);
sem_post(&s12);
sem_wait(&s21);
value= "2nd Iteration THR1 ";
value.append(to_string(thr_1_ID));
q.qPush(value);
sem_post(&s13);
sem_wait(&s31);
sem_post(&sthr1);
}
void *thread2(void* arg){
sem_wait(&idInitializationSemMainToThread);
int *pnum = (int *)arg;
int thr_2_ID = *pnum;
sem_post(&idInitializationSemThreadToMain);
while (true)
{
sem_wait(&sthr2[thr_2_ID]);
sem_wait(&s12);
string readVal = q.qPop();
printString(readVal + ", THR2 "+ to_string(thr_2_ID));
if (thr_2_ID==0)
sem_post(&sthr2[1]);
else
sem_post(&sthr2[0]);
sem_post(&s21);
}
}
void *thread3(void* arg){
sem_wait(&idInitializationSemMainToThread);
int *pnum = (int *)arg;
int thr_3_ID = *pnum;
sem_post(&idInitializationSemThreadToMain);
while (true)
{
sem_wait(&sthr3[thr_3_ID]);
sem_wait(&s13);
string readVal = q.qPop();
printString(readVal + " THR3 " + to_string(thr_3_ID));
if (thr_3_ID == 0)
sem_post(&sthr3[1]);
else
sem_post(&sthr3[0]);
sem_post(&s31);
}
}
int main(){
pthread_t thr1[THR1NUM], thr2[THR2NUM], thr3[THR3NUM];
sem_init(&s12, 0, 0);
sem_init(&s13, 0, 0);
sem_init(&s31, 0, 0);
sem_init(&s21, 0, 0);
sem_init(&printSem, 0, 1);
sem_init(&sthr1, 0, 0);
for (int i = 0; i < 2;i++)
sem_init(&sthr2[i], 0, 0);
for (int i = 0; i < 2;i++)
sem_init(&sthr3[i], 0, 0);
sem_init(&idInitializationSemMainToThread, 0, 0);
sem_init(&idInitializationSemThreadToMain, 0, 0);
int *pnum =(int *) malloc(sizeof(int));
for (int j = 0; j < THR2NUM;j++){
*pnum = j;
pthread_create(&thr2[j], NULL, thread2, (void *)pnum);
sem_post(&idInitializationSemMainToThread);
printString("thr2 "+to_string(j)+ " created");
sem_wait(&idInitializationSemThreadToMain);
}
for (int k = 0; k < THR3NUM;k++){
*pnum = k;
pthread_create(&thr3[k], NULL, thread3,(void *) pnum);
sem_post(&idInitializationSemMainToThread);
printString("thr3 "+to_string(k)+ " created");
sem_wait(&idInitializationSemThreadToMain);
}
for (int i = 0; i < THR1NUM;i++){
*pnum = i;
pthread_create(&thr1[i], NULL, thread1,(void *) pnum);
sem_post(&idInitializationSemMainToThread);
printString("thr1 "+to_string(i)+ " created");
sem_wait(&idInitializationSemThreadToMain);
}
sem_post(&sthr2[0]);
sem_post(&sthr3[0]);
sem_post(&sthr1);
for (int i = 0; i < THR1NUM;i++){
pthread_join(thr1[i], NULL);
printString("thr1 "+to_string(i)+ " joined");
}
for (int i = 0; i < THR2NUM; i++){
pthread_cancel(thr2[i]);
printString("thr2 "+to_string(i)+ " exited");
}
for (int i = 0; i < THR3NUM;i++){
pthread_cancel(thr3[i]);
printString("thr3 "+to_string(i)+ " exited");
sem_post(&printSem);
}
sem_destroy(&s12);
sem_destroy(&s21);
sem_destroy(&s13);
sem_destroy(&s31);
sem_destroy(&sthr1);
free(pnum);
}
// function to print strings atomically.
void printString(string str){
sem_wait(&printSem);
printf("%s\n", str.c_str());
sem_post(&printSem);
}