How can i pass 2-d arrays with different names (but the same structure and data type and size) to a function?
using namespace std;
void OutputArray ();
int A[4][2] = {{1, 2} , {3, 4} , { 5, 7} , {8, 1} };
int B[4][2] = {{5, 6} , {7, 8} , { 3, 9} , {2, 2} };
int main ()
{
OutputArray(A[][2]);
OutputArray(B[][2]);
system("pause");
return 0;
}
void OutputArray(int intNumbersArray[][2])
{
for (int intCounter = 0; intCounter < 4 ; intCounter++)
{
cout << outputArray[intCounter][0] << outputArray[intCounter][1] << endl;
}
}
and consequently have the printed A and B.
after fixing some bugs i got this code to work:
#include <iostream>
using namespace std;
void OutputArray (int intNumbersArray[][2]);
int A[4][2] = {{1, 2} , {3, 4} , { 5, 7} , {8, 1} };
int B[4][2] = {{5, 6} , {7, 8} , { 3, 9} , {2, 2} };
void OutputArray(int intNumbersArray[][2])
{
int intCounter = 0;
for (intCounter = 0; intCounter < 4 ; intCounter++)
{
cout << intNumbersArray[intCounter][0] << intNumbersArray[intCounter][1] << endl;
}
}
int main ()
{
OutputArray(A);
OutputArray(B);
cin;
return 0;
}
you needed #include <iostream> for sin and cout
you needed the signature of OutputArray to contain the parameter int intNumbersArray[][2]
you needed to pass only A and B and not A[][2] B[][2]
In function OutputArray you used outputArray and not intNumbersArray which is the array you meant
Related
I have read a material below and tested some code.
Does IOCP creates its own threads?
My codes are as below:
#include <functional>
#include <stdio.h>
#include <iostream>
#include <crtdbg.h>
#include <conio.h>
#include <array>
#include <unordered_map>
using namespace std;
namespace IOCP_test {
struct myOverlapped {
OVERLAPPED overLapped;
int number;
};
DWORD WINAPI myCallBack(LPVOID completionPort) {
DWORD NumberOfByteTransfered = 0;
VOID* CompletionKey = NULL;
OVERLAPPED* overlappedPointer = NULL;
while (true) {
auto success = GetQueuedCompletionStatus(
(HANDLE)completionPort,
&NumberOfByteTransfered,
(LPDWORD)&CompletionKey,
&overlappedPointer,
INFINITE);
if (success) {
myOverlapped* mO = (myOverlapped*)overlappedPointer;
while (true) {
cout << mO->number << endl;
}
//Sleep(10);
//PostQueuedCompletionStatus(completionPort, 0, 0, overlappedPointer);
}
}
}
void IOCP_test() {
// TODO: sleep을 안걸었는데.. 왜 5개 스레드가 모두 작동할까?
int workerThreadCount = 5;
HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
vector<HANDLE> workerThreadVector;
DWORD NumberOfByteTransfered = 0;
VOID* CompletionKey = NULL;
OVERLAPPED* overlappedPointer = NULL;
for (DWORD i = 0; i < workerThreadCount; i++)
{
HANDLE WorkerThread = CreateThread(NULL, 0, myCallBack, hIOCP, 0, NULL);
workerThreadVector.push_back(WorkerThread);
}
myOverlapped a1;
a1.number = 1;
myOverlapped a2;
a2.number = 2;
myOverlapped a3;
a3.number = 3;
myOverlapped a4;
a4.number = 4;
myOverlapped a5;
a5.number = 5;
if (hIOCP) {
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a1);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a2);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a3);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a4);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a5);
}
char key;
while (true) {
key = _getch();
if (key == 'e') {
break;
}
if (key == 'n') {
cout << endl;
}
}
for (DWORD i = 0; i < workerThreadVector.size(); i++)
{
CloseHandle(workerThreadVector[i]);
}
if (hIOCP) {
CloseHandle(hIOCP);
}
}
//IOCP_test::IOCP_test();
}
int main()
{
IOCP_test::IOCP_test();
_CrtDumpMemoryLeaks();
return 0;
}
I thought, if numberOfConcurrentThreads works, only a thread that cout '1' should be running, not all five threads.
However, result is as below.
All overlapped works were being processed by worker threads..
Why all overlapped works were processed by 5 worker threads?
I think it should be 1 worker thread that works because numberOfConcurrentThreads is 1.
I hope your wise answers.
Thank you for reading.
I figured it out.
It is because I called 'cout' in my worker thread's function.
I think 'cout' invokes IO interrupt for my worker thread, and it makes IOCP signal another worker thread.
My test code is as below.
You can run this code, and press any key except 'e'.('e' is for exit.)
You can see which worker thread works in IOCP.
#include <functional>
#include <stdio.h>
#include <iostream>
#include <crtdbg.h>
#include <conio.h>
#include <array>
#include <unordered_map>
int iocp_test = -1;
namespace IOCP_test {
struct myOverlapped {
OVERLAPPED overLapped;
int number;
};
DWORD WINAPI myCallBack(LPVOID completionPort) {
DWORD NumberOfByteTransfered = 0;
VOID* CompletionKey = NULL;
OVERLAPPED* overlappedPointer = NULL;
while (true) {
auto success = GetQueuedCompletionStatus(
(HANDLE)completionPort,
&NumberOfByteTransfered,
(LPDWORD)&CompletionKey,
&overlappedPointer,
INFINITE);
if (success) {
myOverlapped* mO = (myOverlapped*)overlappedPointer;
while (true) {
iocp_test = mO->number;
}
//Sleep(10);
//PostQueuedCompletionStatus(completionPort, 0, 0, overlappedPointer);
}
}
}
void IOCP_test() {
// sleep을 안걸었는데.. 왜 5개 스레드가 모두 작동할까?
// cout 같은 IO 인터럽트가 워커 스레드에서 호출되면 IOCP에서 그 스레드는 작업 중이 아닌 스레드로 판단하는 것 같다.
int workerThreadCount = 5;
HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 2);
vector<HANDLE> workerThreadVector;
DWORD NumberOfByteTransfered = 0;
VOID* CompletionKey = NULL;
OVERLAPPED* overlappedPointer = NULL;
for (DWORD i = 0; i < workerThreadCount; i++)
{
HANDLE WorkerThread = CreateThread(NULL, 0, myCallBack, hIOCP, 0, NULL);
workerThreadVector.push_back(WorkerThread);
}
myOverlapped a1;
a1.number = 1;
myOverlapped a2;
a2.number = 2;
myOverlapped a3;
a3.number = 3;
myOverlapped a4;
a4.number = 4;
myOverlapped a5;
a5.number = 5;
if (hIOCP) {
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a1);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a2);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a3);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a4);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a5);
}
char key;
while (true) {
key = _getch();
cout << iocp_test;
if (key == 'e') {
break;
}
if (key == 'n') {
cout << endl;
}
}
for (DWORD i = 0; i < workerThreadVector.size(); i++)
{
CloseHandle(workerThreadVector[i]);
}
if (hIOCP) {
CloseHandle(hIOCP);
}
}
//IOCP_test::IOCP_test();
}
int main()
{
IOCP_test::IOCP_test();
_CrtDumpMemoryLeaks();
return 0;
}
I'm learning C++ (14) and currently I'm working on the concurrency part.
I've written a small producer/consumer example to learn and understand condition_variables.
The idea is for one thread to fill up a vector with numbers and then the other to print it to console:
#include <iostream>
#include <thread>
#include <condition_variable>
#include <vector>
#include <atomic>
std::atomic<bool> done{false};
std::mutex ready_mutex;
std::condition_variable ready;
std::vector<int> numbers;
void produce() {
auto idx = 0;
while( true ) {
++idx;
std::lock_guard<std::mutex> lk(ready_mutex);
for(int i = 0; i < 5; ++i) {
numbers.push_back(i);
}
if( 5 == idx) {
done = true;
break;
}
ready.notify_one();
}
ready.notify_one();
}
void consume() {
while( true ) {
std::unique_lock<std::mutex> lk(ready_mutex);
ready.wait(lk, [](){ return !v.empty(); });
std::cout << "(" << numbers.size() << ")" << std::endl;
for(auto x: numbers) {
std::cout << x << ", ";
}
std::cout << std::endl;
numbers.clear();
std::cout << "(" << numbers.size() << ")" << std::endl;
std::cout.flush();
if(done) break;
}
}
int main() {
std::thread t(produce);
std::thread t2(consume);
t.join();
t2.join();
return 0;
}
The problem is that the program is not showing me the expected output.
What I'm expecting is:
(5) 0, 1, 2, 3, 4, (0)
(5) 0, 1, 2, 3, 4, (0)
(5) 0, 1, 2, 3, 4, (0)
(5) 0, 1, 2, 3, 4, (0)
(5) 0, 1, 2, 3, 4, (0)
But what I get is:
(25)
0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4,
(0)
For what I see, the producer thread runs all iterations in one go and then notifies the consumer thread, yet after a few hours I still don't understand why the producer is not waking up the consumer until the end.
Also, I have noticed that this problem persists if instead of using a global vector, I pass it as a reference to the threads:
void producerer(std::vector<int>& v);
void consumer(std::vector<int>& v);
std::vector<int> numbers;
std::thread t(producer, std::ref(numbers));
std::thread t2(consumerer, std::ref(numbers));
OS: Debian 9
Compilers: g++ 6.3.0, clang++ 3.8.1-24
Compiling flags: -Werror -Wextra -Wall -std=c++14 -O0 -g3 -pthread
The issue here is that when the producer releases the lock, you're expecting the consumer to acquire the lock next. However, because of the while loop in the producer, it's possible that the producer re-acquires the lock before the consumer can. If the producer only "produced" once and then yielded to the consumer, there wouldn't be an issue but since you want a ping-pong effect, you need to ensure that the producer waits its turn in the same way the consumer is waiting its turn.
One way to solve this is with another boolean. I'll call it canProduce and set up the producer in the same way you set up the consumer. I'll also repeat the entire process 15 times in main, to minimize the chance of a fluke false positive, should the producer still not be correctly waiting its turn.
#include <iostream>
#include <thread>
#include <condition_variable>
#include <vector>
#include <atomic>
std::atomic<bool> done{false};
std::atomic<bool> canProduce{true};
std::mutex ready_mutex;
std::condition_variable ready;
std::vector<int> numbers;
void produce() {
auto idx = 0;
while( true ) {
++idx;
std::unique_lock<std::mutex> lk(ready_mutex);
ready.wait(lk, [](){ return canProduce == true; });
for(int i = 0; i < 5; ++i) {
numbers.push_back(i);
}
canProduce = false;
// Manually unlocking thread to ensure that when the consumer thread
// wakes up, this thread is unlocked and the consumer thread can acquire
// the lock, otherwise it'll go back to sleep.
lk.unlock();
ready.notify_one();
if( 5 == idx) {
done = true;
break;
}
}
}
void consume() {
while( true ) {
std::unique_lock<std::mutex> lk(ready_mutex);
ready.wait(lk, [](){ return !numbers.empty(); });
std::cout << "(" << numbers.size() << ") ";
for(auto x: numbers) {
std::cout << x << ", ";
}
numbers.clear();
std::cout << "(" << numbers.size() << ")" << std::endl;
std::cout.flush();
if (done) {
break;
} else {
canProduce = true;
lk.unlock();
ready.notify_one();
}
}
}
int main() {
for (int i = 0; i < 15; i++) {
std::cout << "Attempt " << i << std::endl;
std::thread t(produce);
std::thread t2(consume);
t.join();
t2.join();
done = false;
canProduce = true;
}
return 0;
}
Output
Attempt 1
(5) 0, 1, 2, 3, 4, (0)
(5) 0, 1, 2, 3, 4, (0)
(5) 0, 1, 2, 3, 4, (0)
(5) 0, 1, 2, 3, 4, (0)
(5) 0, 1, 2, 3, 4, (0)
Attempt 2
(5) 0, 1, 2, 3, 4, (0)
(5) 0, 1, 2, 3, 4, (0)
(5) 0, 1, 2, 3, 4, (0)
(5) 0, 1, 2, 3, 4, (0)
(5) 0, 1, 2, 3, 4, (0)
...
I'd like to initialize a bunch of variables by calling them in a for loop like this. The effect I'm hoping for is that I'd have three variables at the end aVar = 1, bVar =2, and cVar = 3.
char* variables[] = { "aVar", "bVar", "cVar"};
int values[] = { 1, 2, 3};
void setup(){
for (int i = 0; i < 3; i++){
int String(variables[i]) = values [i];
Serial.println(variables[i]);
}
}
Is there a way to do this?
What you seem to be suggesting is creating a variable at run time whose name is also variable which is not possible. What you could do is create a map and have your keys be entries from variables array and your values be entries from values array.
using namespace std;
int main()
{
char* variables[] = { "aVar", "bVar", "cVar"};
int values[] = { 1, 2, 3};
map<string, int> VariablesMap;
for(int i = 0; i < 3 ; i ++)
{
VariablesMap[variables[i]] = values[i];
}
return 0;
}
Im not sure what to do i want it to print 0000 to ending in BBBB i was trying to use the printf statement anyways, if anyone can help me figure this out that would be great. Thanks
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
char digits[] = "0123456789AB";
for (int column1=0; column1<=12; column1++) {
for (int column2=0; column2<=12; column2++) {
for (int column3=0; column3<=12; column3++) {
for (int column4=0; column4<=12; column4++) {
std::cout<< digits[column2]<<endl;
}
}}}
return(0);
}
The 4 for loops are not the prettiest thing ever, but they should work and I'm not sure it's worth the complications to do it differently. So keep what you have, just print all digits:
std::cout<< digits[column1]<< digits[column2] << digits[column3] << digits[column4]<<endl;
It's better to parametrize the base and the column count to avoid many nested for's.
#include <iostream>
const int columnCount = 4, base = 12;
char digitToChar(int digit) {
if(digit >= 0 && digit <= 9) {
return '0' + digit;
} else {
return 'A' + digit - 10;
}
}
bool increment(int* number) {
int currentColumn = columnCount - 1;
++number[currentColumn];
while(number[currentColumn] == base) {
number[currentColumn] = 0;
--currentColumn;
if(currentColumn < 0) {
return false;
}
++number[currentColumn];
}
return true;
}
void outputNumber(int* number) {
for(int i = 0; i < columnCount; ++i) {
std::cout << digitToChar(number[i]);
}
std::cout << std::endl;
}
int main() {
int number[columnCount] = {0, 0, 0, 0};
bool overflow = false;
do {
outputNumber(number);
overflow = !increment(number);
} while(!overflow);
return 0;
}
I want to use one median function "selectfunction" to choose one of the 2 other functions at random to pass my 2-dim array to the selected function. There is a problem in the median function please help.
#include <iostream>
#define random(x)(rand()%x) // for random number between numbers of 0 and 1
using namespace std;
void proc1 (int iArray[][2]);
void proc2 (int iArray[][2]);
void selectfunction(int iArray[][2]);
int A[4][2] = {{1, 2} , {3, 4} , { 5, 7} , {8, 1} };
void proc1(int iArray[][2])
{
int i= 0;
for (i= 0; i< 4 ; i++)
{
cout << iArray[i][0]<< endl;
}
}
void proc2(int iArray[][2])
{
int i= 0;
for (i= 0; i< 4 ; i++)
{
cout << iArray[i][1] << endl;
}
}
void selectfunction(int iArray[][2])
{
int randmix = random(2);
switch (randmix)
{
case 0:
proc1(int iArray[][2]);
break;
case 1:
proc2(int iArray[][2]);
break;
default:
break;
}
}
int main ()
{
selectfunction(A);
cin;
return 0;
}
case 0:
proc1(int iArray[][2]);
break;
The call should be simply proc1(iArray);. You already know enough to write selectfunction(A); and not selectfunction(int A[][2]); - you should call proc1 and proc2 the same way.
Also, the statement cin;: I'm not sure what you wanted it to do, but be aware that it does nothing at all.