I have program that creates text file and writes some random symbols. How to make that threads be writing those symbols? Here my code below:
static void MyThreadProc(){}
static const char alphanum[] = "0123456789";//this is random symbols I'm using
int stringLength = sizeof(alphanum) - 1;
char genRandom() {
return alphanum[rand() % stringLength];
}
int main() {
String^ fileName = "file.txt";
StreamWriter^ sw = gcnew StreamWriter(fileName);
srand(time(0));
Thread^ myThread1 = gcnew Thread(gcnew ThreadStart(MyThreadProc));
Thread^ myThread2 = gcnew Thread(gcnew ThreadStart(MyThreadProc));
//Here I create my threds
for (int z = 0; z < 21; z++){//This cycle writes 21 random simbol
// myThread1->sw->WriteLine(genRandom());
// myThread1->sw->WriteLine(genRandom()); this threads I want to start writing symbols
sw->WriteLine(genRandom()); //write random symbols
}
sw->Close();
}
This code uses threads to write symbols into text file:
public ref class Simple{
public:
static void Main(){
String^ fileName = "file.txt";
StreamWriter^ sw = gcnew StreamWriter(fileName);
srand(time(0));
Thread^ myTread1 = gcnew Thread(gcnew ThreadStart(MyThreadProc));
myTread1->Start();
for (int z = 0; z < 3; z++){
sw->WriteLine(genRandom());
}
myTread1->Join();
Thread^ myTread2 = gcnew Thread(gcnew ThreadStart(MyThreadProc));
myTread2->Start();
for (int z = 0; z < 3; z++){
sw->WriteLine(genRandom());
}
myTread2->Join();
sw->Close();
}};
Related
I'm trying to have two threads running simultaneously, adding and subtracting from an integer. The thought is to have a random sleep time on them so that they will add or subtract while the other is sleeping. So for example if the thread which adds is asleep for let's say 12 seconds, the thread that subtracts can potentially, subtract not just once, but two or three times before the other wakes.
using namespace System;
using namespace System::Threading;
public ref class RunStack {
private: static Semaphore^ stackSemaphor;
static int itemStack = 10;
public: static void addItem() {
Random^ Rand = gcnew Random();
while (true) {
stackSemaphor->WaitOne();
int Pause = Rand->Next(1, 10);
Pause = Pause * 1000;
Thread::Sleep(Pause);
itemStack++;
Console::CursorLeft = 3;
Console::CursorTop = 3;
Console::WriteLine("Amount in stack: " + itemStack);
stackSemaphor->Release();
}
}
public: static void subItem() {
Random^ Rand = gcnew Random();
while (true) {
stackSemaphor->WaitOne();
int Pause = Rand->Next(1, 10);
Pause = Pause * 1000;
Thread::Sleep(Pause);
itemStack--;
Console::CursorLeft = 3;
Console::CursorTop = 3;
Console::WriteLine("Amount in stack: " + itemStack);
stackSemaphor->Release();
}
}
void Main() {
stackSemaphor = gcnew Semaphore(1, 1);
ThreadStart^ ThreadDelegate1 = gcnew ThreadStart(addItem);
ThreadStart^ ThreadDelegate2 = gcnew ThreadStart(subItem);
Thread^ Thread1 = gcnew Thread(ThreadDelegate1);
Thread1->Priority = ThreadPriority::Normal;
Thread1->Start();
Thread^ Thread2 = gcnew Thread(ThreadDelegate2);
Thread2->Priority = ThreadPriority::Normal;
Thread2->Start();
}
};
int main(array<System::String ^> ^args)
{
Console::Title = "ItemStack";
RunStack^ RunIt = gcnew RunStack();
RunIt->Main();
return 0;
}
This is what I have so far, but I'm not sure how I will have them not wait for each other. As it stands now it only adds 1, then waits for it to subtract 1 before adding 1, and so on. While I want it to be able to add/subtract even if the other is sleeping, and the one has shorter sleep time. I only want it to happen in increments of 1, and not have it add or subtract a random amount.
I'm a beginner at parallel programming. I have 2 function in my code that I want run this 2 function in parallel (multiThread). can you help me?
func 1:
void Navigation::test_end(Graph::Node *node, dtPolyRef endRef, const float *endPos, int endIdPos)
{
int k=0;
//std::ofstream fout("v4.txt", std::ios_base::app | std::ios_base::out);
auto it2 = myMap2.equal_range(endRef);
for (auto it = it2.first; it != it2.second; ++it) {
int m_npolys = 0;
int n=0;
dtPolyRef m_polys[MAX_POLYS];
int j = it->second.size();
for(int i=0;i<j-1;i++){
if(it->second[i]>0){
m_polys[m_npolys++] =it->second[i];
// fout <<it->second[i]<<" ";
}
currentGraph.AddIntraEdge(node->idNode,endIdPos, node->edges[k].idPos, it->second[j-1], m_polys ,m_npolys); //n=m_npolys
k++;
}
}
==========
func 2:
void Navigation::test_start(Graph::Node *node, dtPolyRef startRef, const float *startPos, int startIdPos)
{
int k=0;
//std::ofstream fout("v4.txt", std::ios_base::app | std::ios_base::out);
auto it2 = myMap2.equal_range(startRef);
for (auto it = it2.first; it != it2.second; ++it) {
int m_npolys = 0;
int n=0;
dtPolyRef m_polys[MAX_POLYS];
int j = it->second.size();
for(int i=0;i<j-1;i++){
if(it->second[i]>0){
m_polys[m_npolys++] =it->second[i];
// fout <<it->second[i]<<" ";
}
currentGraph.AddIntraEdge(node->idNode,startIdPos, node->edges[k].idPos, it->second[j-1], m_polys ,m_npolys); //n=m_npolys
k++;
}
}
now i want to run this 2 function in parallel mode in the main function :
test_start(sNode,startRef,startPos,startIdPos);
test_end(eNode,endRef,endPos, endIdPos);
Ok, I'm still trying to figure out how to correctly import FBX vertex and index buffer into DirectX 11. I wrote a controller for doing that and passing the vertex and index buffer to the DX11 renderer, the output should look like a cube but it is not, I only see triangles that don't make sense.
The code is shown below. I did multiply the Z values by -1, though.
What do I need to modify to get the render right?
#pragma once
#include "Array.h"
#include "Vector.h"
#include "fbxsdk.h"
#include <assert.h>
#include "constants.h"
class FbxController
{
public:
FbxController();
~FbxController();
void Import(const char* lFilename)
{
lImporter = FbxImporter::Create(lSdkManager, "");
bool lImportStatus = lImporter->Initialize(lFilename, -1, lSdkManager->GetIOSettings());
if (!lImportStatus) {
printf("Call to FbxImporter::Initialize() failed.\n");
printf("Error returned: %s\n\n", lImporter->GetStatus().GetErrorString());
exit(-1);
}
lScene = FbxScene::Create(lSdkManager, "myScene");
lImporter->Import(lScene);
FbxNode* lRootNode = lScene->GetRootNode();
int childCount = lRootNode->GetChildCount();
FbxNode *node1 = lRootNode->GetChild(0);
const char* nodeName1 = node1->GetName();
fbxsdk::FbxMesh *mesh = node1->GetMesh();
int cpCount1 = mesh->GetControlPointsCount();
fbxsdk::FbxVector4 *controlPoints = mesh->GetControlPoints();
for (int i = 0; i < cpCount1; i++)
{
fbxsdk::FbxVector4 cpitem = controlPoints[i];
printf("%d, %d, %d, %d", cpitem[0], cpitem[1], cpitem[2], cpitem[3] );
VERTEXPOSCOLOR vpc;
vpc.Color.x = 0.5f;
vpc.Color.y = 0.5f;
vpc.Color.z = 0.5f;
vpc.Position.x = cpitem[0];
vpc.Position.y = cpitem[1];
vpc.Position.z = cpitem[2] * -1.0f;
m_vertices.add(vpc);
}
int pvCount = mesh->GetPolygonVertexCount();
int polyCount = mesh->GetPolygonCount();
for (int i = 0; i < polyCount; i++)
{
int polyItemSize = mesh->GetPolygonSize(i);
assert(polyItemSize == 3);
for (int j = 0; j < polyItemSize; j++)
{
int cpIndex = mesh->GetPolygonVertex(i, j);
m_indices.add(cpIndex);
float x = controlPoints[cpIndex].mData[0];
float y = controlPoints[cpIndex].mData[1];
float z = controlPoints[cpIndex].mData[2];
}
}
fbxsdk::FbxMesh *mesh2;
bool isT = mesh->IsTriangleMesh();
FbxNode *node2 = lRootNode->GetChild(1);
FbxNode *node3 = lRootNode->GetChild(2);
//lImporter->Destroy();
}
Array<VERTEXPOSCOLOR> GetVertexPosColors()
{
return m_vertices;
}
Array<unsigned int> getIndexBuffer()
{
return m_indices;
}
protected:
FbxManager *lSdkManager;
FbxIOSettings *ios;
FbxImporter *lImporter;
bool lImportStatu;
FbxScene *lScene;
private:
Array<VERTEXPOSCOLOR> m_vertices;
Array<unsigned int> m_indices;
};
I think you have some problems in your index buffer creation.
You simply gives an index for each vertex, and index buffer not working that way.
let me know if you solve this.
how to return few Strings from threads and link it to one String ?
I use CLI/C++, threads in windows forms. This code should divide message from user to n(nThreads) texts and in each thread should encipher message.
Finally it must concat all results to one.
Actually I did something like this:
public: ref class ThreadExample
{
public:
static String^ inputString;
static String^ outputString;
static array<String^>^ arrayOfThreads = gcnew array <String^>(nThreads);
static int iterator;
static void ThreadEncipher()
{
string input, output;
MarshalString(inputString, input);
output = CaesarCipher::encipher(input);
outputString = gcnew String(output.c_str());
arrayOfThreads[iterator] = outputString;
}
Function where I use threads:
array<String^>^ ThreadEncipherFuncCpp(int nThreads, string str2){
array<String^>^ arrayOfThreads = gcnew array <String^>(nThreads);
string loopSubstring;
messageLength = str2.length();
int numberOfSubstring = messageLength / nThreads;
int isModulo = messageLength % nThreads;
array<Thread^>^ xThread = gcnew array < Thread^ >(nThreads);
int j;
//loop dividing text to threads
for (int i = 0; i < nThreads; i++)
{
j = i;
if (i == 0 && numberOfSubstring != 0)
loopSubstring = str2.substr(0, numberOfSubstring);
else if ((i == nThreads - 1) && numberOfSubstring != 0){
if (isModulo != 0)
loopSubstring = str2.substr(numberOfSubstring*i, numberOfSubstring + isModulo);
else
loopSubstring = str2.substr(numberOfSubstring*i, numberOfSubstring);
}
else if (numberOfSubstring == 0){
loopSubstring = str2.substr(0, isModulo);
i = nThreads - 1;
}
else
loopSubstring = str2.substr(numberOfSubstring*i, numberOfSubstring);
xThread[i] = gcnew Thread(gcnew ThreadStart(&ThreadExample::ThreadEncipher));
}
auto start = chrono::system_clock::now();
for (int i = 0; i < nThreads; i++){
ThreadExample::iterator = i;
ThreadExample::inputString = gcnew String(loopSubstring.c_str());
xThread[i]->Start();
}
for (int i = 0; i < nThreads; i++){
xThread[i]->Join();
}
auto elapsed = chrono::system_clock::now() - start;
long long milliseconds = chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
cppTimer = milliseconds;
arrayOfThreads = ThreadExample::arrayOfThreads;
delete xThread;
return arrayOfThreads;
}
I'm going to take a guess here and say that the program ran without error, but your output was blank.
The reason the output is blank is because of the static class initializer. This is executed earlier than you think it is: As soon as you reference the class in any way, the static initializer runs. Therefore, when you try to execute ThreadExample::inputString = "Some example text. Some example text2.";, the static class initializer has already run, and your array of threads is set.
To fix this, move that code out of the static initializer, and into the method where you create the threads.
Also, a more general note on C++/CLI: If you're trying to learn C++, please don't use C++/CLI. C++/CLI is not the same thing as C++. C++/CLI has all the complexities of C++, all the complexities of C#, and some complexities of its own thrown in for good measure. It should be used when it's needed to interface .Net code to C++ code, not as a primary development language.
I appreciate any help, and would like to thank you in advance. I'm working on a project for one of my classes. Essentially performing merge sort using multithreading and reference classes. In main I'm just trying to create an initial thread that will begin the recursive mergesort. Each time the array is split a new thread is spawned to handle that subroutine. I don't need all of it done, i just don't under stand why my Thread constructor and ThreadStart delegate are not working. Thanks again!!
#include <iostream>
#include <vector>
#include <string>
#include <time.h>
#include <cstdlib>
using namespace System;
using namespace System::Threading;
public ref class MergeSort
{
private: int cnt;
public: MergeSort()
{
cnt = 0;
}
public: void mergeSort(char a[], int from, int to)
{
Thread^ current = Thread::CurrentThread;
if(from == to)
return;
int mid = (from + to)/2;
//Sort the first and the second half
//addThread(a, from, mid);
//addThread(a, mid+1, to);
//threads[0]->Join();
//threads[1]->Join();
merge(a, from, mid, to);
}
public: void merge(char a[], int from, int mid, int to)
{
Thread^ current = Thread::CurrentThread;
while (current ->ThreadState == ThreadState::Running)
{
int n = to-from + 1; // Size of range to be merged
std::vector<char> b(n);
int i1 = from; //Next element to consider in the first half
int i2 = mid + 1; //Next element to consider in the second half
int j = 0; //Next open position in b
//As long as neight i1 or i2 is past the end, move the smaller element into b
while(i1 <= mid && i2 <= to)
{
if(a[i1] < a[i2])
{
b[j] = a[i1];
i1++;
}
else
{
b[j] = a[i2];
i2++;
}
j++;
}
//Copy any remaining entries of the first half
while(i1 <= mid)
{
b[j] = a[i1];
i1++;
j++;
}
while(i2 <= to)
{
b[j] = a[i2];
i2++;
j++;
}
//Copy back from temporary vector
for(j = 0; j < n; j++)
a[from+j] = b[j];
}
}
};
void main()
{
char A[10];
for(int i = 0; i < 10; i++)
{
A[i] = ((char) ((rand() % (122-65)) + 65));
}
array<Thread^>^ tr = gcnew array<Thread^>(10);
MergeSort^ ms1 = gcnew MergeSort();
ThreadStart^ TS = gcnew ThreadStart(ms1, &MergeSort::mergeSort(A, 0, 10));
tr[0] = gcnew Thread(TS);
tr[0] -> Start();
system("pause");
}
The issue you are facing here is how to construct a ThreadStart delegate. You are trying to do too many things in the ThreadStart constructor. You cannot pass in arguments at this point because all it is looking for is a start location for the thread.
The delegate should be:
ThreadStart^ TS = gcnew ThreadStart(ms1, &MergeSort::mergeSort);
Since however you are passing in some state, I would recommend doing a bit more research on how that is done using C++\CLI. This MSDN topic should give you a start.
Edit:
Never mind, the problem was that I had to change the parameter of the method I tried to pass from Int32 to Object^.
I´m having a similar issue, though i think my problem are not the arguments. I´m passing those through during thread->Start().
I think my problem is rather that I´m trying to start the thread using a method of a ref class.
invalid delegate initializer -- function does not match the delegate type
Is the error I´m getting. Any Ideas?
void AddForcesAll() {
for (int index = 0; index < n; index++) {
Thread^ thread = gcnew Thread (gcnew ParameterizedThreadStart(this, &Bodies::AddForces));
thread->Start(index);
}
The Syntax worked fine for me for non referenced classes.