How to share variable from thread to many thread in QT - c++

I have problem to share variable from thread1 to thread2 and main.cpp. My variable in thread1 has a name "value". I have shared to thread2 and make an increment in main.cpp. This is my code in thread1.h :
#ifndef THREAD1_H
#define THREAD1_H
#include <QCoreApplication>
#include <QDebug>
class thread1 : public QObject
{
Q_OBJECT
public:
thread1();
void changeValue(int input);
int value;
};
#endif // THREAD1_H
My code in thread1.cpp:
#include "thread1.h"
void thread1::changeValue(int input)
{
if(input > 10 && input < 15)
qDebug() << "hello world 1...";
else if(input > 15 && input < 20)
qDebug() << "Hello world 2...";
}
thread1::thread1()
{
}
My code in thread2.h:
#ifndef THREAD2_H
#define THREAD2_H
#include <QThread>
#include "thread1.h"
class thread2 : public QThread
{
Q_OBJECT
public:
thread2(QObject *parent = 0);
void checkthread1();
private:
thread1 *thr;
};
#endif // THREAD2_H
My code in thread2.cpp:
#include "thread2.h"
void thread2::checkthread1()
{
thr = new thread1();
qDebug() << "thread 1 value from thread2.c = " << QString::number(thr->value);
thr->changeValue(thr->value);
}
thread2::thread2(QObject *parent) : QThread(parent)
{
}
My code in main.cpp:
#include <QCoreApplication>
#include <QTime>
#include <QDebug>
#include "thread1.h"
#include "thread2.h"
//Global Variable
thread2 *thr2;
thread1 *thr1;
void delay(int waited)
{
QTime dieTime = QTime::currentTime().addMSecs(waited);
while(QTime::currentTime() < dieTime)
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
thr1 = new thread1();
thr2 = new thread2();
while(1)
{
thr1->value += 1;
qDebug() << "thread 1 value from main.c = " << QString::number(thr1->value);
thr2->checkthread1();
delay(1000);
}
return a.exec();
}
And my result is:
thread 1 value from main.c = "17"
thread 1 value from thread2.c = "48"
thread 1 value from main.c = "18"
thread 1 value from thread2.c = "0"
thread 1 value from main.c = "19"
thread 1 value from thread2.c = "7143547"
thread 1 value from main.c = "20"
thread 1 value from thread2.c = "0"
thread 1 value from main.c = "21"
thread 1 value from thread2.c = "16"
Hello world 2...
thread 1 value from main.c = "22"
thread 1 value from thread2.c = "56"
thread 1 value from main.c = "23"
thread 1 value from thread2.c = "8"
thread 1 value from main.c = "24"
thread 1 value from thread2.c = "0"
thread 1 value from main.c = "25"
thread 1 value from thread2.c = "0"
thread 1 value from main.c = "26"
thread 1 value from thread2.c = "0"
thread 1 value from main.c = "27"
thread 1 value from thread2.c = "0"
thread 1 value from main.c = "28"
thread 1 value from thread2.c = "48"
thread 1 value from main.c = "29"
thread 1 value from thread2.c = "1818326560"
thread 1 value from main.c = "30"
thread 1 value from thread2.c = "0"
thread 1 value from main.c = "31"
thread 1 value from thread2.c = "16"
Hello world 2...
thread 1 value from main.c = "32"
thread 1 value from thread2.c = "0"
thread 1 value from main.c = "33"
thread 1 value from thread2.c = "0"
"value" in main.cpp make a good increment like what i want. I have desired "value" in thread2.cpp have same value like in main.cpp. But the result give me another value. I'm just little bit confused. Why "value" in thread2.cpp is change?

You seem to still be struggling with the basics, such as keeping track of the objects you have. You claim to have two threads, but that's wrong: you keep creating new threads every time you call checkthread1().
You also fail to call delete, which you should only do after you know a thread has exited.
Since you have so many threads, you're not actually changing the same value. That's causing the problem you see. You'll need an atomic value once you fixed the thread spam

QMutex and other similar, when you use qmutex you guarantee that only one thread at the moment have access to variable. You can see examples on qt documentation site.
threads qt

Related

create thread but process shows up?

#include <unistd.h>
#include <stdio.h>
#include <cstring>
#include <thread>
void test_cpu() {
printf("thread: test_cpu start\n");
int total = 0;
while (1) {
++total;
}
}
void test_mem() {
printf("thread: test_mem start\n");
int step = 20;
int size = 10 * 1024 * 1024; // 10Mb
for (int i = 0; i < step; ++i) {
char* tmp = new char[size];
memset(tmp, i, size);
sleep(1);
}
printf("thread: test_mem done\n");
}
int main(int argc, char** argv) {
std::thread t1(test_cpu);
std::thread t2(test_mem);
t1.join();
t2.join();
return 0;
}
Compile it with g++ -o test test.cc --std=c++11 -lpthread
I run the program in Linux, and run top to monitor it.
I expect to see ONE process however I saw THREE.
It looks like std::thread is creating threads, why do I end up with getting processes?
Linux does not implement threads. It only has Light Weight Processes (LWP) while pthread library wraps them to provide POSIX-compatible thread interface. The main LWP creates its own address space while each subsequent thread LWP shares address space with main LWP.
Many utils, such as HTOP (which seems to be on the screenshot) by default list LWP. In order to hide thread LWPs you can open Setup (F2) -> Display Options and check Hide kernel threads and Hide userland process threads options. There is also an option to highlight threads - Display threads in different color.

Qt SLOT not triggered by the SIGNAL emitted from std::async in QTest environment

I was investigating the topic of async programming with Qt and I reached the conclusion that it is safe to emit signals from whatever kind of threads (although QT docs only mention QThread), as more or less described here. Now I faced the problem testing my application. To simplify as much as possible: I have the async operation, which might notify MainWindow by emitting the SIGNAL. It works fine in the production, but it doesn't work in unit-test environment with QTest. Complete example (project structure flat, no subdirs):
CMakeLists.txt
cmake_minimum_required(VERSION 3.0.0)
project(QtFailure)
enable_testing()
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
if(CMAKE_VERSION VERSION_LESS "3.7.0")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()
find_package(Qt5 COMPONENTS Core Widgets Test REQUIRED)
add_library(QtFailure source.cpp header.hpp)
target_include_directories(QtFailure PUBLIC .)
target_link_libraries(QtFailure
pthread
Qt5::Core
Qt5::Widgets
)
add_executable(main main.cpp)
target_link_libraries(main QtFailure)
add_executable(QtFailureTest test.cpp)
target_link_libraries(QtFailureTest
QtFailure
Qt5::Test
)
header.hpp
#pragma once
#include <QMainWindow>
#include <QWidget>
#include <future>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget* parent = nullptr);
~MainWindow();
void start();
int counter_value();
signals:
void sendSignal();
private slots:
bool triggerSlot();
private:
bool stop_;
std::future<void> async_oper_;
};
source.cpp
#include "header.hpp"
#include <QMainWindow>
#include <QWidget>
#include <QObject>
#include <QDebug>
#include <future>
#include <chrono>
#include <thread>
static int counter = 0;
MainWindow::MainWindow(QWidget* parent):
QMainWindow(parent),
stop_(false),
async_oper_()
{
QObject::connect(this, SIGNAL(sendSignal()), this, SLOT(triggerSlot()));
}
MainWindow::~MainWindow()
{
stop_ = true;
}
int MainWindow::counter_value()
{
return counter;
}
void MainWindow::start()
{
if (async_oper_.valid()) return;
emit sendSignal(); // this one works
async_oper_ = std::async(std::launch::async, [this]()
{
while (!stop_)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
emit sendSignal(); // this one doesn't work in tests
}
});
}
bool MainWindow::triggerSlot()
{
qDebug() << "triggerSlot: " << counter;
counter++;
}
test.cpp
#include "header.hpp"
#include <QSignalSpy>
#include <QDebug>
#include <QtTest/QtTest>
#include <memory>
#include <chrono>
#include <thread>
class MyFixture: public QObject
{
Q_OBJECT
private:
std::unique_ptr<MainWindow> sut_;
private slots:
void init()
{
qDebug("MyFixture init");
sut_.reset(new MainWindow);
}
void cleanup()
{
qDebug("MyFixture cleanup");
sut_.reset();
}
void example_test()
{
QSignalSpy spy(sut_.get(), SIGNAL(sendSignal()));
sut_->start();
std::this_thread::sleep_for(std::chrono::seconds(1));
qDebug() << "num signals: " << spy.count();
qDebug() << "counter value: " << sut_->counter_value();
}
};
QTEST_MAIN(MyFixture)
#include "test.moc"
main.cpp
#include <QApplication>
#include "header.hpp"
int main(int argc, char** argv)
{
QApplication a(argc, argv);
MainWindow w;
w.start();
w.show();
return a.exec();
}
The output from my test is
PASS : MyFixture::initTestCase()
QDEBUG : MyFixture::example_test() MyFixture init
QDEBUG : MyFixture::example_test() triggerSlot: 0
QDEBUG : MyFixture::example_test() num signals: 10
QDEBUG : MyFixture::example_test() counter value: 1
QDEBUG : MyFixture::example_test() MyFixture cleanup
PASS : MyFixture::example_test()
PASS : MyFixture::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 1003ms
which means that the slot was triggered only once, by the signal emitted from the main thread.
The output from main is:
...
triggerSlot: 25
triggerSlot: 26
triggerSlot: 27
etc ...
which is the expected behavior. Why is there a difference between QTest environment and normal QApplication in main? What should I do to correct tests behavior?
I must use standard C++ threads, because my GUI is just a facade to real non-Qt related system, which has different kinds of async opers, callbacks etc.
Sorry for the amount of code, but with QT I cannot really squeeze it in a few lines.
=== EDIT ===
Specifying Qt::DirectConnection connection attribute will "fix" the issue in the QTest environment. But this is something I cannot do in most cases, because GUI actions must take place in the main thread (e.g. scync oper emits signal to trigger QPixmap refresh);
The signal emit code is correct. Queued Signal-Slot connection requires event loop to be running in the receiver thread for signal delivery:
Events to that object are dispatched by that (receiver) thread's event loop.
Event loop of the receiver thread aren't working because you block it in the line
// just suspends current thread without running any event loop
std::this_thread::sleep_for(std::chrono::seconds(1));
That is, event loop of the receiver thread are blocking throughout the whole example_test() method body. There is no one line which runs an event loop within itself. That is not Qt Test or QTEST_MAIN() issue.
Here is how you can fix that:
void example_test()
{
QSignalSpy spy(sut_.get(), SIGNAL(sendSignal()));
sut_->start();
QElapsedTimer timer;
timer.start();
while(timer.elapsed() < 1000)
{
spy.wait(10); // event loop runs here
}
qDebug() << "num signals: " << spy.count();
qDebug() << "counter value: " << sut_->counter_value();
}
QSignalSpy::wait():
Starts an event loop that runs until the given signal is received.
Optionally the event loop can return earlier on a timeout (in
milliseconds).
Returns true if the signal was emitted at least once in timeout milliseconds, otherwise returns false.

Non-blocking reading in background Qt thread on Linux caused EAGAIN

Here is the minimal example of background data reading in Qt (available in GitLab). The program open file and read data byte-by-byte. The flow is the following:
// Flow
//
// Widget Worker
// +
// | create thread
// | create worker +
// | move worker to thread |
// | start thread |
// | |
// | start onStart |
// |---------------------------------->|
// | |
// | onReady ready |
// |<----------------------------------| .--<--.
// | semaphore acquire | | |
// | print data | | ^
// | | v |
// | semaphore release | | |
// |---------------------------------->| `-->--
// | |
// | |
// | finished |
// | |
// | delete worker -
// | detete thread
// | quit application
// -
The following code sometimes (about 1:30) caused EAGAIN error code when reading data from regular file.
$ ./rdqt ../main.cpp
Success 32768
$ ./rdqt ../main.cpp
Resource temporarily unavailable 32768
How is it possible for regular file? Or is this result of incorrect multithreading implementation?
.
├── main.cpp
├── Widget.cpp
├── Widget.h
├── Worker.cpp
└── Worker.h
main.cpp
#include <QApplication>
#include "Widget.h"
int main (int argc, char * argv [])
{
QApplication application (argc, argv);
if (argc > 1) {
Widget widget (argv [1]);
widget.show ();
return application.exec ();
}
return EXIT_FAILURE;
}
Widget.h
#ifndef READ_DATA_WIDGET_H
#define READ_DATA_WIDGET_H
#include <QWidget>
#include <QThread>
#include <QSemaphore>
#include "Worker.h"
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget (const char *, QWidget * parent = nullptr);
virtual ~Widget ();
signals:
void start ();
public slots:
void onReady (char);
private:
QThread * thread;
QSemaphore * semaphore;
Worker * worker;
};
#endif//READ_DATA_WIDGET_H
Widget.cpp
#include "Widget.h"
#include <QDebug>
#include <QApplication>
Widget::Widget (const char * path, QWidget * parent)
: QWidget (parent)
, thread {new QThread}
, semaphore {new QSemaphore (1)}
, worker {new Worker (path, semaphore)}
{
connect (this, & Widget::start, worker, & Worker::onStart);
connect (worker, & Worker::ready, this, & Widget::onReady);
connect (worker, & Worker::finish, [this]() {
thread->quit ();
/*QApplication::quit ();*/
});
worker->moveToThread (thread);
thread->start ();
emit start ();
}
Widget::~Widget ()
{
worker->deleteLater ();
thread->deleteLater ();
}
void Widget::onReady (char /*c*/)
{
/*qDebug ("%c", c);*/
semaphore->release ();
}
Worker.h
#ifndef READ_DATA_WORKER_H
#define READ_DATA_WORKER_H
#include <QObject>
#include <QSemaphore>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker (const char *, QSemaphore *);
virtual ~Worker () = default;
signals:
void ready (char);
void finish ();
public slots:
void onStart ();
private:
const char * path;
QSemaphore * semaphore;
};
#endif//READ_DATA_WORKER_H
Worker.cpp
#include "Worker.h"
#include <QDebug>
#include <unistd.h>
#include <fcntl.h>
Worker::Worker (const char * path, QSemaphore * semaphore)
: QObject ()
, path {path}
, semaphore {semaphore}
{
}
void Worker::onStart ()
{
int file = open (path, O_RDONLY);
char b;
while (read (file, & b, 1) > 0) {
semaphore->acquire ();
emit ready (b);
}
qDebug () << strerror (errno) << (fcntl (file, F_GETFL) /*& O_NONBLOCK*/);
emit finish ();
}
Main answer
Ok, I finally got it. The errno is set internally when locking a mutex by Qt either when calling semaphore->acquire (); or when emitting a signal with emit ready (b); (Qt uses synchronisation objects for queued connections, obviously). Here's how to debug where errno change happens. I added the following line at the beginning of Worker::onStart:
qDebug() << QString("0x%1").arg(reinterpret_cast<quint64>(&errno), 0, 16);
and set a breakpoint on the next line in debugger. Having this address (e.g. 0x7fffda6ce668) I added a memory breakpoint in gdb with watch *0x7fffda6ce668 in the gdb console (if you use Qt Creator, enable Window -> Views -> Debugger Log). I immediately got the backtrace for the errno change:
#0 0x00007ffff63964ae in syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:42
#1 0x00007ffff6eb0610 in QBasicMutex::lockInternal() () from /home/(my-user-name)/apps/Qt5.5.0/5.5/gcc_64/lib/libQt5Core.so.5
#2 0x00007ffff70a7199 in QCoreApplication::postEvent(QObject*, QEvent*, int) () from /home/(my-user-name)/apps/Qt5.5.0/5.5/gcc_64/lib/libQt5Core.so.5
#3 0x00007ffff70d3286 in QMetaObject::activate(QObject*, int, int, void**) () from /home/(my-user-name)/apps/Qt5.5.0/5.5/gcc_64/lib/libQt5Core.so.5
#4 0x000000000040494f in Worker::ready (this=0x8d1550, _t1=0 '\\000') at moc_Worker.cpp:142
#5 0x0000000000403dee in Worker::onStart (this=0x8d1550) at ../qt/Worker.cpp:63
Now, QMutex is implemented in corelib/thread/qmutex_linux.cpp and uses a futex which causes errno == 11 sometimes. I've no idea why this happens, sorry, might be someone's bug ;) You can check the qmutex_linux.cpp code and try to find relevant info on the net for yourself. If you are interested if a specific API call produces an error you can set errno=0 before this call and check it after the call. Btw, I tested it without any file io just sending a dummy character with ready(0), the result was the same. So the problem is not file io.
Previous answer (mostly irrelevant after your code changes)
I think what you're trying to achieve with a QMutex alone is classically done with QMutex and QWaitCondition:
void Worker::onStart ()
{
// ...
while (true) {
QMutexLocker locker(&mutex);
if(read (file, & b, 1) <= 0)
break;
emit ready (b);
// waitCondition unlocks the mutex and
// waits till waitCondition wakeAll/wakeOne is called
// signalling that Widget has finished processing
waitCondition.wait(&mutex);
}
// ...
}
void Worker::onRequest ()
{
// re-locks the mutex and continues the while cycle
waitCondition.wakeAll();
}
Here waitCondition is a member variable like mutex. I haven't checked this code. It's just for illustration of the idea, you may need to change it a little. Links for reference: QWaitCondition description and usage example.

Thread Scheduler Error Visual Studio 2013 vs 2015

I recently upgraded some projects from VS2013 to VS2015 and I have found some problems with my threaded code. The issue seems to be that a thread that is waiting on a mutex to get unlocked is not getting control when another thread unlocks the mutex. Since the other thread is a loop that locks the mutex, does something, then unlocks it, the result is that thread running the loop many times and the other thread waiting >10sec for control. Below is a very small sample program that reproduces the bug for me.
#include "stdafx.h"
#include <thread>
#include <mutex>
#include <iostream>
std::mutex print_guard_;
int i = 0;
void RenderLoop()
{
while (true) {
print_guard_.lock();
std::cout << "Render: " << i << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(200));
print_guard_.unlock();
std::this_thread::yield();
}
}
void Print()
{
print_guard_.lock();
std::cout << "Main Thread: " << i << std::endl;
print_guard_.unlock();
}
int main()
{
std::thread* thread_ = new std::thread(RenderLoop);
while (true) {
Print();
}
return 0;
}
The error occurs both with and without the yield command in the RenderLoop function. In Visual Studio 2015 I get something like:
Render: 0
Render: 0
Render: 0
Render: 0
Render: 0
Render: 0
Render: 0
Render: 0
Render: 0
... (continues for a few seconds or longer)
Main Thread: 0
Main Thread: 0
Main Thread: 0
Main Thread: 0
Main Thread: 0
Main Thread: 0
Render: 0
Render: 0
Render: 0
...
and on VS2013 I get
Render: 0
Main Thread: 0
Render: 0
Main Thread: 0
Render: 0
Main Thread: 0
Render: 0
Main Thread: 0
Render: 0
Main Thread: 0
Render: 0
Main Thread: 0
Render: 0
Main Thread: 0
Render: 0
Main Thread: 0
Render: 0
Main Thread: 0
Render: 0
Main Thread: 0
Render: 0
Main Thread: 0
Anyone have any ideas on how to force the thread to give up control?

Threading performance degradation on Solaris 11 (sparc) using C++11 with GCC 4.8.0 and multiple threads

I created a simple program to measure thread performance. I ripped out portions of a larger program in order to illustrate my point. Hopefully it's not too terrible to read.
Here is the program:
#include <sstream>
#include <thread>
#include <list>
#include <map>
#include <mutex>
#include <condition_variable>
#include <iostream>
#include <string.h>
std::mutex m_totalTranMutex;
int m_totalTrans = 0;
bool m_startThreads = false;
std::condition_variable m_allowThreadStart;
std::mutex m_threadStartMutex;
std::map<int,std::thread::native_handle_type> m_threadNativeHandles;
char *my_strdup(const char *str)
{
size_t len = strlen(str);
char *x = (char *)malloc(len+1);
if(x == nullptr)
return nullptr;
memcpy(x,str,len+1);
return x;
}
void DoWork()
{
char abc[50000];
char *s1, *s2;
std::strcpy(abc, "12345");
std::strcpy(abc+20000, "12345");
s1 = my_strdup(abc);
s2 = my_strdup(abc);
free(s1);
free(s2);
}
void WorkerThread(int threadID)
{
{
std::unique_lock<std::mutex> lk(m_threadStartMutex);
m_allowThreadStart.wait(lk, []{return m_startThreads;});
}
double transPerSec = 1 / 99999;
int transactionCounter = 0;
int64_t clockTicksUsed = 0;
std::thread::native_handle_type handle = m_threadNativeHandles[threadID];
std::chrono::high_resolution_clock::time_point current = std::chrono::high_resolution_clock::now();
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
std::chrono::high_resolution_clock::time_point end = start + std::chrono::minutes(1);
int random_num_loops = 0;
double interarrivaltime = 0.0;
double timeHolderReal = 0.0;
while(current < end)
{
std::chrono::high_resolution_clock::time_point startWork = std::chrono::high_resolution_clock::now();
for(int loopIndex = 0; loopIndex < 100; ++loopIndex)
{
for(int alwaysOneHundred = 0; alwaysOneHundred < 100; ++alwaysOneHundred)
{
DoWork();
}
}
std::chrono::high_resolution_clock::time_point endWork = std::chrono::high_resolution_clock::now();
++transactionCounter;
clockTicksUsed += std::chrono::duration_cast<std::chrono::milliseconds>(endWork - startWork).count();
current = std::chrono::high_resolution_clock::now();
}
std::lock_guard<std::mutex> tranMutex(m_totalTranMutex);
std::cout << "Thread " << threadID << " finished with " << transactionCounter << " transaction." << std::endl;
m_totalTrans += transactionCounter;
}
int main(int argc, char *argv[])
{
std::stringstream ss;
int numthreads = atoi(argv[1]);
std::list<std::thread> threads;
int threadIds = 1;
for(int i = 0; i < numthreads; ++i)
{
threads.push_back(std::thread(&WorkerThread, threadIds));
m_threadNativeHandles.insert(std::make_pair(threadIds, threads.rbegin()->native_handle()));
++threadIds;
}
{
std::lock_guard<std::mutex> lk(m_threadStartMutex);
m_startThreads = true;
}
m_allowThreadStart.notify_all();
//Join until completion
for(std::thread &th : threads)
{
th.join();
}
ss << "TotalTran" << std::endl
<< m_totalTrans << std::endl;
std::cout << ss.str();
}
Application usage: app N
where app is the name of the application and N is the number of threads to produce. The program runs for 1 minute.
On windows, I build this program with Visual Studio 2012. I execute the program on a quad core I7 (4 cores, 2 threads per core).
I get the following:
simplethread 1
Thread 1 finished with 1667 transaction.
TotalTran
1667
simplethread 2
Thread 1 finished with 1037 transaction.
Thread 2 finished with 1030 transaction.
TotalTran
2067
simplethread 3
Thread 3 finished with 824 transaction.
Thread 2 finished with 830 transaction.
Thread 1 finished with 837 transaction.
TotalTran
2491
simplethread 4
Thread 3 finished with 688 transaction.
Thread 2 finished with 693 transaction.
Thread 1 finished with 704 transaction.
Thread 4 finished with 691 transaction.
TotalTran
2776
simplethread 8
Thread 2 finished with 334 transaction.
Thread 6 finished with 325 transaction.
Thread 7 finished with 346 transaction.
Thread 1 finished with 329 transaction.
Thread 8 finished with 329 transaction.
Thread 3 finished with 338 transaction.
Thread 5 finished with 331 transaction.
Thread 4 finished with 330 transaction.
TotalTran
2662
E:\Development\Projects\Applications\CPUBenchmark\Debug>simplethread 16
Thread 16 finished with 163 transaction.
Thread 15 finished with 169 transaction.
Thread 12 finished with 165 transaction.
Thread 9 finished with 170 transaction.
Thread 10 finished with 166 transaction.
Thread 4 finished with 164 transaction.
Thread 13 finished with 166 transaction.
Thread 8 finished with 165 transaction.
Thread 6 finished with 165 transaction.
Thread 5 finished with 168 transaction.
Thread 2 finished with 161 transaction.
Thread 1 finished with 159 transaction.
Thread 7 finished with 160 transaction.
Thread 11 finished with 161 transaction.
Thread 14 finished with 163 transaction.
Thread 3 finished with 161 transaction.
TotalTran
2626
These numbers look a little poor. I was expecting a lot closer to double going from one thread doing X work to 2 threads doing 2X work on this system. The threads did do about the same amount of work but not as much in one minutes time.
It get's even stranger when I move to solaris.
On Solaris 11, using GCC 4.8.0, I build this program as follows:
gcc -o simple simpleThreads.cpp -I. -std=c++11 -DSOLARIS=1 -lstdc++ -lm
when i run "./simple 1", i get
Thread 1 finished with 19686 transaction.
TotalTran
19686
for "./simple 2", I get:
Thread 1 finished with 5248 transaction.
Thread 2 finished with 2484 transaction.
TotalTran
7732
On Solaris, the 2 thread case is much slower. I can't figure out what I'm doing wrong. I'm new to c++11 constructs and threads. So it's a double whammy. gcc -v shows the thread model is posix. Any help would be appreciated.