C++ 如何在整个程序中访问有关线程的信息
问题1:我试图为每个线程命名,以便它可以在整个程序中使用,但收到错误,如“请求“planes[t]”中的成员“fid”,这是非类类型“pthread\u t”。它指的是使用planes[t].tid或使用planes[t].startState。我不确定如何获取/保存每个线程的这些值 问题2:一旦我有了一个线程的startState,我如何将该线程发送到takeoff()函数(一系列开关状态和printfs) 问题3:应该向StartState函数传递什么?我试图让每个线程记住它的开始状态,以便在代码的后面我可以让航班“着陆”或“起飞” 以下是相关代码:于2006年10月22:37更新C++ 如何在整个程序中访问有关线程的信息,c++,c,multithreading,C++,C,Multithreading,问题1:我试图为每个线程命名,以便它可以在整个程序中使用,但收到错误,如“请求“planes[t]”中的成员“fid”,这是非类类型“pthread\u t”。它指的是使用planes[t].tid或使用planes[t].startState。我不确定如何获取/保存每个线程的这些值 问题2:一旦我有了一个线程的startState,我如何将该线程发送到takeoff()函数(一系列开关状态和printfs) 问题3:应该向StartState函数传递什么?我试图让每个线程记住它的开始状态,以便
#include <pthread.h>
#include <stdio.h>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <unistd.h>
#include <algorithm>
#include <time.h>
#include <ctime>
#define NUM_THREADS 3 //3 flights
using std::queue;
using std::vector;
pthread_mutex_t runway1lock;
pthread_mutex_t runway2lock;
bool run1occupied;
bool run2occupied;
struct flight_data{ //each plane has these characteristics
//void *FlightID;
long fid;
int startState; // if start=1 ==> taking off ::: if start=2 ==> landing
int flyTime; //fly == randomly generated time (order) of takeoff/land
};
struct flight_data flightinfo[NUM_THREADS];
void *FlightID(void *flightid){
struct flight_data *my_flights;
my_flights = (struct flight_data*)flightid;
int taskid;
taskid = my_flights->fid;
// long fid;
// fid = (long)flightid;
// printf("Flight #%1d\n", tid);
pthread_exit(NULL);
}
void Start(struct flight_data my_flights){
my_flights = (struct flight_data)my_flights;
int startState;
srand(time(0));
my_flights.startState = rand() % 2+1;
std::string startstring;
if(my_flights.startState == 1){
startstring = "Taking off";
}
if(my_flights.startState == 2){
startstring = "Landing";
}
for(int i = 1; i<NUM_THREADS+1; i++){
std::cout << "Start state for Flight # " << i << " is " << startstring << std::endl;
}
}
void takeoff(struct flight_data my_flights){
my_flights = (struct flight_data)my_flights;
for(int i = 1; i<NUM_THREADS+1; i++){
int state = my_flights.startState;
switch(state){
case 1:{ //G (GATE)
std::cout << "Flight # " << flightinfo[i].fid << " is listed as waiting at the gate." << std::endl;
std::cout << "Flight # " << flightinfo[i].fid << "'s position in queue for runway: " << flightinfo[i].flyTime << std::endl;
sleep(3);
state = 2;
break;
}
case 2: { //Q (queue) -- sets order for use of runway
queue<pthread_t> queue;
vector<int> flightTimes;
int soonestFlightTime = 10;
flightTimes.push_back(flightinfo[i].flyTime); //put all flight times into a vector called flightTimes
std::sort(flightTimes.begin(), flightTimes.end()); //sort the vector of flightTimes low to high
std::reverse(flightTimes.begin(), flightTimes.end()); //flips vector -- high(front) to low(back)
while(!flightTimes.empty()){
if (flightinfo[i].flyTime == flightTimes.back()){ //if a thread has the soonest flight time
queue.push(i); //then put the flight in the runway queue
flightTimes.pop_back(); //pop off the soonest flight time
}
}
while(!queue.empty()){
if(flightinfo[i].fid == queue.front()){
state = 3;
queue.pop();
sleep(3);
}
}
break;
}
case 3: { //CLR (clearance for runway)
std::cout << "Flight # " << flightinfo[i].fid << " has clearance to move to the runway." << std::endl; //will go in order of queue
if(run1occupied){
sleep(3);
}
// else if(collide){
// state = 7;
// }
else{
state = 4;
}
break;
}
case 4: { //RTO (runway takeoff)
pthread_mutex_lock(&runway1lock);
run1occupied = true;
std::cout << "Flight # " << flightinfo[i].fid << " is taking off. Runway occupied. Stand by." << std::endl;
sleep(3);
pthread_mutex_unlock(&runway1lock);
run1occupied = false;
state = 5;
break;
}
case 5: { //CZ (cruise)
std::cout << "Flight # " << flightinfo[i].fid << " is reaching proper altitude and cruising toward destination." << std::endl;
sleep(3);
// if(!collide){
state = 6;
// }
// else{
// state = 7; //collision!!!
// }
break;
}
case 6: { //RMV (remove from monitoring list)
std::cout << "Flight # " << flightinfo[i].fid << " has been removed from the monitoring list." << std::endl;
break;
}
case 7:{ //COLL (collision)
std::cout << "Collision in the air. There were many casualties." << std::endl;
break;
}
}
}
}
void landing(struct flight_data my_flights){
my_flights = (struct flight_data)my_flights;
for (int i = 0; i<NUM_THREADS; i++){
int state = my_flights.startState;
switch(state){
case 1:{ //ENTR (enter monitoring list)
state = 2;
break;
}
case 2:{ //Q (queue)
//if not the first thing in the queue then state = 4;
//otherwise state = 3;
}
case 3:{ //RWL (runway land)
state = 5;
break;
}
case 4:{ //HVR (hover)
//if first in queue then state = 3;
//otherwise stay here
//if collision state = 7;
}
case 5:{ //CLR (clearance to move to gate)
//if collision state = 7
//otherwise state = 6;
}
case 6:{ //G (gate)
}
case 7:{ //COLL (collision)
}
}
}
}
/*
bool collision(){
bool collide;
//random
if(){
collide = true;
}
else{
collide = false;
}
return collide;
}*/
int main(int argc, char *argv[]){
pthread_t flights[NUM_THREADS]; //pthread_t keeps a thread ID after the thread is created with pthread_create()
//it's like an index on a vector of threads
int *taskids[NUM_THREADS];
int rc;
long t;
for (t=1; t<=NUM_THREADS; t++){ //loop creates threads(flights)
printf("In main: Creating flight %1d\n", t);
flightinfo[t].fid= t;
rc = pthread_create(&flights[t], NULL, FlightID, (void *)&flights[t]);
if (rc){
printf("ERROR: return code from pthread_create() is %d\n", rc);
return (-1);
}
printf("Created flight %1d\n", t);
// Start(flightinfo[t]);
flightinfo[t].startState = rand() % 2+1;
std::cout << flightinfo[t].startState << std::endl;
if((flightinfo[t].startState)==1){
std::cout << "Flight # " << flightinfo[t].fid << " is listed with start state as " << flightinfo[t].startState << std::endl;
takeoff(flightinfo[t]);
//go to takeoff function and go through switch case
}
if((flightinfo[t].startState)==2){
std::cout << "Flight # " << flightinfo[t].fid << " is listed with start state as " << flightinfo[t].startState << std::endl;
landing(flightinfo[t]);
//go to landing function and go through switch case
}
}
pthread_exit(NULL);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义NUM_线程3//3个航班
使用std::queue;
使用std::vector;
pthread_mutex_t runway1锁;
pthread_mutex_t runway2lock;
有人占了便宜;
被占用的bool run2;
struct flight_data{//每架飞机都有这些特征
//void*FlightID;
长fid;
int startState;//如果开始=1==>起飞:::如果开始=2==>着陆
int flyTime;//fly==随机生成的起飞/着陆时间(顺序)
};
struct flight_data flightinfo[NUM_THREADS];
void*FlightID(void*FlightID){
结构航班数据*我的航班;
我的航班=(结构航班数据*)航班ID;
int taskid;
taskid=我的航班->fid;
//长fid;
//fid=(长)flightid;
//printf(“航班#%1d\n”,tid);
pthread_exit(NULL);
}
无效启动(结构航班数据我的航班){
我的航班=(结构航班数据)我的航班;
int startState;
srand(时间(0));
my_flights.startState=rand()%2+1;
std::字符串开始字符串;
如果(my_flights.startState==1){
startstring=“起飞”;
}
如果(my_flights.startState==2){
startstring=“着陆”;
}
对于(int i=1;i所有这些变量似乎都存储在flights
数组中,而不是planes
数组中。您似乎混淆了pthread\u t管理变量planes
与包含飞行数据的变量flights
pthread_t管理变量planes
,由pthread库使用,您实际上应该只将其用作pthread库调用的参数,否则就不用管它了,不用担心它。将变量planes
视为您创建的存储区域,然后将其交给pthread库使用nd通过这样做,您将该变量的所有权授予pthread库
因此,第一个任务是分离并区分pthread管理和线程正在操作的实际数据之间的差异
您在多个地方使用pthread管理变量planes
,就好像它是一个飞行数据变量一样。它不是。请将planes
替换为flights
if((flights[t].startState)==1){
std::cout << "Flight # " << flights[t].fid << " is listed as waiting at the gate." << std::endl;
void takeoff();
//go to takeoff function and go through switch case
}
if((flights[t].startState)==2){
std::cout << "Flight # " << flights[t].fid << " is listed as waiting to land." << std::endl;
//go to landing function and go through switch case
}
我假设您想用一些随机启动状态设置特定航班的启动状态。因此,我希望源代码如下所示,因为我假设您对设置特定航班的启动状态感兴趣,并且循环除了运行随机数生成器NUM_THREADS
但是我没有检查你的逻辑,范围是否正确
my_flights->startState = rand() % 1+2;
建议的行动方案
你应该把线程看作是一个小程序或应用程序。对于这个简单的例子,我建议你首先编写飞行逻辑,而不必担心线程。因此,如果你从一个函数开始,比如说flyplanefright()
向其传递一个flight变量,然后此函数调用其他函数来执行各种操作,当flight结束时,它返回给调用者,您可能会处于线程的良好位置。在为单个flight设置好逻辑后,您可以使用pthread库通过初始化飞行数据,然后创建一个线程,该线程使用FlyPlaneFlight()
你还需要考虑时间和交互。对于这种模拟,我怀疑你会想要拥有<代码> FrimePrimeFlash()。
函数,在其中更改飞行数据,然后线程将休眠一两秒钟。作为开始测试,使用迭代次数确定的for循环,然后退出,例如:
for (int i = 0; i < 100; i++) {
// modify the flight data
sleep(1000); // sleep for a second (1000 milliseconds) then repeat
}
其思想是将飞机飞行视为一个对象,飞行所需的所有数据都在struct flight\u data
struct中,并且在大多数情况下,您可以忽略pthread库,该库不涉及实际飞行模拟,而是用于允许模拟多个飞行对象。因此,您可以创建e多个线程,每个线程都有自己的飞行数据,然后使用相同的代码来处理飞行数据。你做一些随机化,这样所有不同的飞行都会有不同的历史,它们会做不同的事情
编辑
您的main将有一个如下所示的循环
for (t=0; t<NUM_THREADS; t++){ //loop creates threads(flights)
std::cout << "In main: Creating flight " << t+1 << std::endl;
flights[t].fid= t+1;
rc = pthread_create(&planes[t], NULL, FlightID, (void *)&flights[t]);
if (rc){
std::cout << "ERROR: return code from pthread_create() is " << rc << std::endl;
return (-1);
}
std::cout << "Created flight " << t << std::endl;
}
pthread_exit(NULL); // exit the main thread and allow remaining threads to complete
根据2006年10月10日22:37的源代码更新编辑#2
#include <pthread.h>
#include <stdio.h>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <unistd.h>
#include <algorithm>
#include <time.h>
#include <ctime>
#define NUM_THREADS 3 //3 flights
using std::queue;
using std::vector;
pthread_mutex_t runway1lock;
pthread_mutex_t runway2lock;
bool run1occupied;
bool run2occupied;
struct flight_data{ //each plane has these characteristics
//void *FlightID;
long fid;
int startState; // if start=1 ==> taking off ::: if start=2 ==> landing
int flyTime; //fly == randomly generated time (order) of takeoff/land
};
struct flight_data flightinfo[NUM_THREADS];
void *FlightID(void *flightid){
struct flight_data *my_flights;
my_flights = (struct flight_data*)flightid;
int taskid;
taskid = my_flights->fid;
// long fid;
// fid = (long)flightid;
// printf("Flight #%1d\n", tid);
pthread_exit(NULL);
}
void Start(struct flight_data my_flights){
my_flights = (struct flight_data)my_flights;
int startState;
srand(time(0));
my_flights.startState = rand() % 2+1;
std::string startstring;
if(my_flights.startState == 1){
startstring = "Taking off";
}
if(my_flights.startState == 2){
startstring = "Landing";
}
for(int i = 1; i<NUM_THREADS+1; i++){
std::cout << "Start state for Flight # " << i << " is " << startstring << std::endl;
}
}
void takeoff(struct flight_data my_flights){
my_flights = (struct flight_data)my_flights;
for(int i = 1; i<NUM_THREADS+1; i++){
int state = my_flights.startState;
switch(state){
case 1:{ //G (GATE)
std::cout << "Flight # " << flightinfo[i].fid << " is listed as waiting at the gate." << std::endl;
std::cout << "Flight # " << flightinfo[i].fid << "'s position in queue for runway: " << flightinfo[i].flyTime << std::endl;
sleep(3);
state = 2;
break;
}
case 2: { //Q (queue) -- sets order for use of runway
queue<pthread_t> queue;
vector<int> flightTimes;
int soonestFlightTime = 10;
flightTimes.push_back(flightinfo[i].flyTime); //put all flight times into a vector called flightTimes
std::sort(flightTimes.begin(), flightTimes.end()); //sort the vector of flightTimes low to high
std::reverse(flightTimes.begin(), flightTimes.end()); //flips vector -- high(front) to low(back)
while(!flightTimes.empty()){
if (flightinfo[i].flyTime == flightTimes.back()){ //if a thread has the soonest flight time
queue.push(i); //then put the flight in the runway queue
flightTimes.pop_back(); //pop off the soonest flight time
}
}
while(!queue.empty()){
if(flightinfo[i].fid == queue.front()){
state = 3;
queue.pop();
sleep(3);
}
}
break;
}
case 3: { //CLR (clearance for runway)
std::cout << "Flight # " << flightinfo[i].fid << " has clearance to move to the runway." << std::endl; //will go in order of queue
if(run1occupied){
sleep(3);
}
// else if(collide){
// state = 7;
// }
else{
state = 4;
}
break;
}
case 4: { //RTO (runway takeoff)
pthread_mutex_lock(&runway1lock);
run1occupied = true;
std::cout << "Flight # " << flightinfo[i].fid << " is taking off. Runway occupied. Stand by." << std::endl;
sleep(3);
pthread_mutex_unlock(&runway1lock);
run1occupied = false;
state = 5;
break;
}
case 5: { //CZ (cruise)
std::cout << "Flight # " << flightinfo[i].fid << " is reaching proper altitude and cruising toward destination." << std::endl;
sleep(3);
// if(!collide){
state = 6;
// }
// else{
// state = 7; //collision!!!
// }
break;
}
case 6: { //RMV (remove from monitoring list)
std::cout << "Flight # " << flightinfo[i].fid << " has been removed from the monitoring list." << std::endl;
break;
}
case 7:{ //COLL (collision)
std::cout << "Collision in the air. There were many casualties." << std::endl;
break;
}
}
}
}
void landing(struct flight_data my_flights){
my_flights = (struct flight_data)my_flights;
for (int i = 0; i<NUM_THREADS; i++){
int state = my_flights.startState;
switch(state){
case 1:{ //ENTR (enter monitoring list)
state = 2;
break;
}
case 2:{ //Q (queue)
//if not the first thing in the queue then state = 4;
//otherwise state = 3;
}
case 3:{ //RWL (runway land)
state = 5;
break;
}
case 4:{ //HVR (hover)
//if first in queue then state = 3;
//otherwise stay here
//if collision state = 7;
}
case 5:{ //CLR (clearance to move to gate)
//if collision state = 7
//otherwise state = 6;
}
case 6:{ //G (gate)
}
case 7:{ //COLL (collision)
}
}
}
}
/*
bool collision(){
bool collide;
//random
if(){
collide = true;
}
else{
collide = false;
}
return collide;
}*/
int main(int argc, char *argv[]){
pthread_t flights[NUM_THREADS]; //pthread_t keeps a thread ID after the thread is created with pthread_create()
//it's like an index on a vector of threads
int *taskids[NUM_THREADS];
int rc;
long t;
for (t=1; t<=NUM_THREADS; t++){ //loop creates threads(flights)
printf("In main: Creating flight %1d\n", t);
flightinfo[t].fid= t;
rc = pthread_create(&flights[t], NULL, FlightID, (void *)&flights[t]);
if (rc){
printf("ERROR: return code from pthread_create() is %d\n", rc);
return (-1);
}
printf("Created flight %1d\n", t);
// Start(flightinfo[t]);
flightinfo[t].startState = rand() % 2+1;
std::cout << flightinfo[t].startState << std::endl;
if((flightinfo[t].startState)==1){
std::cout << "Flight # " << flightinfo[t].fid << " is listed with start state as " << flightinfo[t].startState << std::endl;
takeoff(flightinfo[t]);
//go to takeoff function and go through switch case
}
if((flightinfo[t].startState)==2){
std::cout << "Flight # " << flightinfo[t].fid << " is listed with start state as " << flightinfo[t].startState << std::endl;
landing(flightinfo[t]);
//go to landing function and go through switch case
}
}
pthread_exit(NULL);
}
在源代码中,您有一个全局数组变量,flights
,您正试图通过源代码直接访问该变量。这是一个导致问题的错误。您需要做的是让线程创建调用将flights的特定数组元素分配给t
for (t=0; t<NUM_THREADS; t++){ //loop creates threads(flights)
std::cout << "In main: Creating flight " << t+1 << std::endl;
flights[t].fid= t+1;
rc = pthread_create(&planes[t], NULL, FlightID, (void *)&flights[t]);
if (rc){
std::cout << "ERROR: return code from pthread_create() is " << rc << std::endl;
return (-1);
}
std::cout << "Created flight " << t << std::endl;
}
pthread_exit(NULL); // exit the main thread and allow remaining threads to complete
void FlyPlaneFlight (struct flight_data *my_flights)
{
for (int i = 0; i < 100; i++) {
switch (my_flights->startState) {
case 1:
std::cout << "Flight # " << my_flights->fid << " is listed as waiting at the gate." << std::endl;
// now move the flight state to the next state.
break;
case 2:
std::cout << "Flight # " << my_flights->fid << " is listed as waiting to land." << std::endl;
// now move the flight state to the next state.
break;
// other case statements for other flight states and moving between the
// various flight states.
}
sleep (1000); // sleep this thread for one second (1000 milliseconds) then repeat
}
}
rc = pthread_create(&planes[t], NULL, FlightID, (void *)&flights[t]);