我正在编写一个程序,它将使用位操作来评估竞争条件,然后还将使用信号量锁定/解锁来消除这些竞争条件。
我用“./raceTest 5 6 3 6 unlock”运行该程序。所有输出都很好。但现在它与解锁arg崩溃了。
当我尝试使用这些args编译它时,我的程序崩溃了:./ rasTest 5 6 3 6 lock(或任何带有“lock”的args)
这就是输出带有“lock”命令。它现在崩溃了...即使它没有崩溃“解锁”并正确显示一切。
./raceTest 5 6 3 6 lock
lock
nBuffers is 5
mWorkers is 6
sleepMin is 3
sleepMax is 6
randarray 4
randarray 3
randarray 6
randarray 3
randarray 4
randarray 4
Segmentation fault
我曾尝试使用gdb,当我运行该程序时,我从gdb
中收到此错误Starting program: /mnt_nfs/home3/ugrad3/ariley/Desktop/cs361/hw5/raceTest
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x2aaaaaaab000
[Thread debugging using libthread_db enabled]
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct NULL not valid
Program received signal SIGABRT, Aborted.
0x0000003156430265 in raise () from /lib64/libc.so.6
有人可以告诉我这意味着什么吗?它早先工作了。但现在它不起作用,我没有做任何事情......
// raceTest program
#include <string>
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
/* union semun is defined by including <sys/sem.h> */
#else
/* according to X/OPEN we have to define it ourselves */
union semun
{
int val; // value for SETVAL
struct semid_ds *buf; // buffer for IPC_STAT, IPC_SET
unsigned short *array; // array for GETALL, SETALL
struct seminfo *_buf; // buffer for IPC_INFO
};
#endif
static int sem_id = 0;
static int sem_semvalue();
static void del_semvalue();
static int semaphore_p();
static int semaphore_v();
using namespace std;
// struct for the threads
typedef struct thread
{
int nbuffers;
int ID;
double sleepTime;
int semID;
int mutexID;
int *buffer;
int nReadErrors;
} Thread_data;
void *worker(void *targ)
{
cout << "In worker function" << endl;
// cast back to a struct variable to use
Thread_data *data = (Thread_data*) targ;
int errors=0;
for (int i=0 ; i < data->nbuffers; i++)
{
// READ the value of buffers at that thread's ID, starting from current ID
int read = data->buffer[data->ID];
usleep(data->sleepTime);
// see if the value changed after sleeping
int secondRead = data->buffer[data->ID];
if (secondRead != read)
{
cout << " Worker " << data->buffer[data->ID] << " reported change from " << read << " to secondRead " << secondRead;
cout << " in buffer " << i << endl;
errors ++;
}
read = (read + data->ID) % (data->nbuffers); // next read
usleep(data->sleepTime);
secondRead = data->buffer[read];
if (secondRead != read)
{
cout << " Worker " << data->buffer[data->ID] << "reported change from " << read << " to secondRead " << secondRead;
cout << " in buffer " << i << endl;
errors ++;
}
// write operations to do
read = (read + data->ID) % (data->nbuffers);
usleep(data->sleepTime);
// add to the buffer array, or the WRITE
data->buffer[read] = secondRead + ( 1 << (data->ID - 1) );
}
data->nReadErrors = errors; // update 4.
pthread_exit(NULL);
}
int main (int argc, char * argv[])
{
int i; // handle all command line arguements
int nBuffers = 0;
int mWorkers = 0;
int sleepMin = 0;
int sleepMax = 0;
srand(time(NULL));
key_t key = IPC_PRIVATE;
int rErrors = 0;
int wErrors = 0;
// parse command line arguments
// USAGE: raceTest nBuffers nWorkers sleepMin sleepMax [ randSeed ] [ -lock | -nolock ]
for (i=1 ; i<argc-1 ; i++)
{
// Check input
string s = argv[i];
int num = atoi( s.c_str() ); // UPDATE 5
//cout << "argv at " << i << " is " << num << endl;
if (num == 0)
{
cout << "USAGE: raceTest nBuffers nWorkers sleepMin sleepMax [ randSeed ] [ -lock | - nolock ]" << endl;
cout << "Exiting..." << endl;
exit(-1);
}
}
string s = argv[i++];
cout << s << endl;
// set variables to command line arguments
// nBuffers has restrictions
nBuffers = atoi(argv[1]);
if ( nBuffers <= 2 || nBuffers >= 32)
{
cout << "nBuffers is the wrong size. Exiting" << endl;
exit (-1);
if (nBuffers != 3 || nBuffers != 7 || nBuffers != 11 || nBuffers != 17 || nBuffers !=5
|| nBuffers != 13 || nBuffers != 19 || nBuffers != 23 || nBuffers != 31 || nBuffers != 29)
{
cout << "nBuffers must be prime. Exiting" << endl;
exit (-2);
}
}
mWorkers = atoi(argv[2]); cout << "nBuffers is " << nBuffers << endl;
sleepMin = atoi(argv[3]); cout << "mWorkers is " << mWorkers << endl;
sleepMax = atoi(argv[4]); cout << "sleepMin is " << sleepMin << endl;
cout << "sleepMax is " << sleepMax << endl;
int buffers[nBuffers];
double randWorkers[mWorkers];
// initialize the arrays
for (int i=0 ; i<nBuffers ; i++)
buffers[i] = 0;
for (int i=0 ; i<mWorkers ; i++)
{
// generate random number between sleepMin and sleepMax
int temp = rand() % (sleepMax - sleepMin + 1) + sleepMin;
randWorkers[i] = temp;
cout << "randarray " << randWorkers[i] << endl;
}
// sort the numbers in decreasing order
for (int i=0 ; i<mWorkers ; i++)
{
for (int j=0 ; j< mWorkers ; j++)
{
if (randWorkers[i] < randWorkers[j])
{
cout << "here" << endl;
// simple sorting
double temp = randWorkers[i];
randWorkers[i] = randWorkers[j];
randWorkers[j] = temp;
cout << randWorkers[i] << " ";
}
}
}
// other sorting method
//sort (randWorkers, sizeof(randWorkers), greater<double>);
// create an array of M structs and populate each with values needed
// for the threads
Thread_data threadVals[mWorkers];
for (int i=0 ; i<mWorkers ; i++)
{
threadVals[i].nbuffers = nBuffers;
threadVals[i].ID = i+1;
threadVals[i].sleepTime = randWorkers[i];
threadVals[i].semID = -1;
threadVals[i].mutexID = -1;
threadVals[i].nReadErrors = 0;
threadVals[i].buffer = buffers;
}
// create an array of M (threads) where each runs the
// worker() function
pthread_t tid[nBuffers];
for (int i=0 ; i<mWorkers ; i++)
{
// don't do any locking
if ( strcmp (s.c_str(), "nolock") == 0)
{
// pass a pointer to one of the structs
int value = pthread_create (&tid[i], NULL, worker, &threadVals[i]);
if (value != 0)
{
perror ("thread creation failed");
exit(-3);
}
else
cout << "successful creation for " << tid[nBuffers] << endl;
}
// use semaphores for the locking
else if (strcmp(s.c_str() , "lock") == 0)
{
/*cout << "B-----" << endl;
int sem_id = semget(key, 1, IPC_CREAT|0666);
if (sem_id < 0)
{
perror ( "Cannot create sem_id");
exit(-5);
}
cout << "A-----" << endl; */
;
}
}
// wait for all of the threads to finish
for (int j=0 ; j<mWorkers ; j++)
{
pthread_join(tid[j], NULL);
}
for (int i=0 ; i< nBuffers ; i++)
{
int size = 2^ mWorkers - 1;
if (buffers[i] == size)
break; // this particular index is the same
cout << "Bad bits for buffer[" << i <<"] = " ;
int diff = size ^ buffers[i];
for (int j=0 ; j <mWorkers ; j++)
{
// perform a binary OR and then binary AND
int position = (diff) & (1<<j);
//cout << buffer[position] << W" ";
if (position)
cout << j << " " ;
wErrors++;
}
cout << endl;
}
// figure the total number of read errors
for (int i=0 ; i<mWorkers ; i++)
rErrors = rErrors + threadVals[i].nReadErrors;
cout << "Total Errors: " << "read errors: " << rErrors << " write errors " << wErrors << endl;
return 0;
}
EDIT :: 这就是我做bt时所得到的,恐怕我真的不明白这些东西是什么意思......
Program received signal SIGSEGV, Segmentation fault.
0x000000315643471a in ____strtoll_l_internal () from /lib64/libc.so.6
(gdb) bt
#0 0x000000315643471a in ____strtoll_l_internal () from /lib64/libc.so.6
#1 0x0000003156431bd2 in atoi () from /lib64/libc.so.6
#2 0x00000000004010a5 in main (argc=1, argv=0x7fffffffded8) at raceTest.cpp:171
(gdb) up
#1 0x0000003156431bd2 in atoi () from /lib64/libc.so.6
(gdb)
#2 0x00000000004010a5 in main (argc=1, argv=0x7fffffffded8) at raceTest.cpp:171
171 nBuffers = atoi(argv[1]);
(gdb)
Initial frame selected; you cannot go up.
(gdb) print nBuffers
$1 = 0
第二次编辑:无论我是刚刚进行碰撞还是使用信号量。我做的唯一改变是将数组参数从nBuffers更改为nWorkers,然后测试rand的输出以查看它是否产生了未定义的行为。
[ariley@bert hw5]$ ./raceTest 5 6 3 6 lock
5
6
3
6
5beforenBuffers is 5
mWorkers is 6
sleepMin is 3
sleepMax is 6
value of temp4
randarray 4
value of temp6
randarray 6
value of temp3
randarray 3
value of temp5
randarray 5
value of temp4
randarray 4
value of temp6
randarray 6
successful creation for 6300416
In worker function
successful creation for 6300416
successful creation for 47840834492736
Segmentation fault
答案 0 :(得分:2)
pthread_t tid[nBuffers];
应该是
pthread_t tid[mWorkers];
除非参数集是'nolock'(不是'unlock'),否则不会初始化tid []数组,因此使用无效的参数调用pthread_join(tid [i],NULL)。
标记。
答案 1 :(得分:0)
有人可以告诉我这意味着什么吗?
这意味着你做了(相当于)这个:
char *cp = NULL;
std::string s(cp); // throws logic_error