Я пытаюсь реализовать класс, который создает поток, увеличивает значение и отправляет его в другой поток, число которых определяется как (значение * значение)% число потоковошибка сегментации при создании потока
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <cstdlib>
#include <vector>
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
volatile int counter = 0;
volatile int maxval = 0;
volatile int next = 0;
extern "C" void *func(void *p);
class Worker {
private:
pthread_t thread = 0;
int nth = 0;
int nproc = 0;
public:
Worker() {};
Worker(int _nproc, int _nth) {
nth = _nth;
nproc = _nproc;
};
void start() {
pthread_create(&thread, NULL, func, NULL); // Line 27
};
void wait() {
while (nth != next) {
pthread_cond_wait(&cv, &m);
}
};
void notify() {
pthread_cond_broadcast(&cv);
};
void run() {
while (counter != maxval) {
pthread_mutex_lock(&m);
Worker::wait();
if (counter != maxval) {
printf("%d %d\n", nth, counter);
++counter;
}
next = (counter * counter) % nproc;
Worker::notify();
pthread_mutex_unlock(&m);
}
};
void join() {
pthread_join(thread, NULL);
}
};
extern "C" void *func(void *p) {
Worker *w = reinterpret_cast<Worker*>(p);
w->run();
return NULL;
}
int main(int argc, char *argv[]) {
int nthreads = atoi(argv[1]);
maxval = atoi(argv[2]);
std::vector<Worker> workers;
for (int i = 0; i != nthreads; ++i) {
workers.push_back(Worker(nthreads, i));
}
for (int i = 0; i != workers.size(); ++i) {
workers[i].start();
}
for (int i = 0; i != workers.size(); ++i) {
workers[i].join();
}
return 0;
}
Невозможно проверить, если алгоритм является правильным, так как я получаю Segmentation Ошибка когда я называю pthread_create (строка 27)
Это то, что GDB сказал:
#0 0x0000000000400f5a in Worker::wait (this=0x0) at ht19-4.cpp:30
#1 0x0000000000400fd5 in Worker::run (this=0x0) at ht19-4.cpp:40
#2 0x0000000000400d26 in func (p=0x0) at ht19-4.cpp:57
#3 0x00007ffff76296aa in start_thread (arg=0x7ffff6f4f700)
at pthread_create.c:333
#4 0x00007ffff735eeed in clone()
at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
Может ли кто-нибудь объяснить, что именно происходит в этой функции, пожалуйста? Как это реализовать правильно?
Большое спасибо.
@EliasVanOotegem Я думаю, что это выше основного. –
Основываясь на вашей трассировке стека, кажется, что ваш сбой внутри чего-то вызывает 'func()'. Запись 'Worker :: run (this = 0x0)' предполагает, что у вас есть неинициализированный указатель на объект; как вы его инициализируете? – mah
Приятно видеть некоторые gdb в вопросе на C++. :) – erip