Lost prints from pthread c++ - c++

I start to use pthread of C++ and have made a simple exampe for multi threads(3). But what i see is that I always got prints from two threads. why?
#include <iostream>
#include <string>
#include <pthread.h>
using namespace std;
int N=10;
void* run(void* arg) {
char* msg = (char*)arg;
for(int i; i<=N; ++i) std::cout<<msg<<std::endl;
}
int main(int argc, char* argv[]) {
if (argc > 1) N = stoi(argv[1]);
pthread_t t1,t2,t3;
pthread_create(&t1,NULL,run,(void*)"xxx");
pthread_create(&t2,NULL,run,(void*)" howdy");
pthread_create(&t3,NULL,run,(void*)" wrold");
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_join(t3,NULL);
return 0;
}
Prints like:
howdy
wrold
howdy
wrold

It's undefined behaviour, anything can happen.
For example on my machine it doesn't print anything at all.
i is not initialized.
void* run has to return something (e.g.: return NULL;)

Related

C + + cannot find the thread it created on ubuntu 18

I write a simple c++ code. In my code, I create two threads, then I name the two threads TCPCall30003Proc and TCPCall30004Proc, but I can not find them using top command with option -H. My os is ubuntu 18.
#include <pthread.h>
#include <thread>
#include <stdio.h>
#include <time.h>
#include <iostream>
#include <stdlib.h>
#include <chrono>
#include <unistd.h>
void f1(int num)
{
printf("1\n");
while(1)
{
sleep(1);
}
}
void f2(int num)
{
printf("2\n");
while(1)
{
sleep(1);
}
}
int main(int argc, char **argv)
{
std::thread thd_1 = std::thread(f1, 1);
std::thread thd_2 = std::thread(f2, 1);
pthread_setname_np(thd_1.native_handle(), "TCPCall30003Proc");
pthread_setname_np(thd_2.native_handle(), "TCPCall30004Proc");
while(1)
{
sleep(1);
}
return 0;
}
From the pthread_setname_np manual page:
The thread name is a meaningful C language string, whose length is restricted to 16 characters, including the terminating null byte ('\0').
[Emphasis mine]
You names are 17 characters, including the null-terminator.
If you check what pthread_setname_np returns it should return -1 and with errno set to ERANGE.
You need to shorten your names.

Multithreading requests with queue cpp

Im trying to make multithreaded proxy checker in c++, when I start the threads and lock it all threads wait till the request is finished. I tried to remove the locks but that doesn't help either. Im using the cpr library to make the requests, the documentation can be found here: https://whoshuu.github.io/cpr/advanced-usage.html.
Reproduceable example:
#include <stdio.h>
#include <pthread.h>
#include <iostream>
#include <queue>
#include <mutex>
#include <cpr/cpr.h>
#include <fmt/format.h>
#define NUMT 10
using namespace std;
using namespace fmt;
std::mutex mut;
std::queue<std::string> q;
void* Checker(void* arg) {
while (!q.empty()) {
mut.lock();
//get a webhook at https://webhook.site
string protocol = "socks4";
string proxyformatted = format("{0}://{1}", protocol, q.front());
auto r = cpr::Get(cpr::Url{ "<webhook url>" },
cpr::Proxies{ {"http", proxyformatted}, {"https", proxyformatted} });
q.pop();
mut.unlock();
}
return NULL;
}
int main(int argc, char** argv) {
q.push("138.201.134.206:5678");
q.push("185.113.7.87:5678");
q.push("5.9.16.126:5678");
q.push("88.146.196.181:4153");
pthread_t tid[NUMT]; int i;
int thread_args[NUMT];
for (i = 0; i < NUMT; i++) {
thread_args[i] = i;
pthread_create(&tid[i], NULL, Checker, (void*) &thread_args);
}
for (i = 0; i < NUMT; i++) {
pthread_join(tid[i], NULL);
fprintf(stderr, "Thread %d terminated\n", i);
}
return 0;
}
Thanks in advance.
I suggest to implement a wrapper class for your queue that will hide the mutex.
That class can provide push(std::string s) and bool pop(std::string& s) that returns true and populate s if the queue wasn't empty or false othervise. Then your worker threads can simply loop
std::string s;
while(q.pop(s)) {
...
}

How to pass a value from a thread to main in c++

I am a complete beginner in OS. The problem I am having is that I want to receive a value from a thread into the main process. A garbage value is printed in the main. Please elaborate so I can know my mistake.
Here is my code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <iostream>
#include<string.h>
#include <sys/wait.h>
#include<pthread.h>
#include <sys/types.h>
#include<sys/stat.h>
#include<errno.h>
#include<fcntl.h>
#include<time.h>
#include <fstream>
#include<vector>
using namespace std;
void *thread_1(void *arg);
int main(int argc, char* argv[])
{
void *temp;
pthread_t t1;
pthread_create(&t1, NULL,thread_1,NULL);
pthread_join(t1,&temp);
int *num = (int*)temp;
cout<<"Value in main: "<<*num<<endl;
}
void *thread_1(void *arg)
{
int number = 5;
int* value = &number;
cout<<"Value in thread: "<<*value<<endl;
pthread_exit((void*)value);
}
You have two ways to do this:
Pass a pointer to an integer as the argument to the thread, and have the thread modify the argument to hold the value you want.
Have the thread allocate a value on the heap and return a pointer to that memory. Then clean it up later.
#include <iostream>
#include <pthread.h>
void *thread_1(void *arg);
void *thread_2(void *arg);
int main(int argc, char* argv[])
{
int value = 0;
pthread_t t1;
pthread_create(&t1, NULL,thread_1, &value);
pthread_join(t1, NULL);
std::cout<<"Value in main: "<<value<<std::endl;
int* value2 = NULL;
pthread_t t2;
pthread_create(&t2, NULL,thread_2, NULL);
pthread_join(t2, reinterpret_cast<void**>(&value2));
if (value2) {
std::cout<<"Value in main: "<<*value2<<std::endl;
delete value2;
}
}
void *thread_1(void *arg)
{
int* value = static_cast<int*>(arg);
*value = 5;
std::cout<<"Value in thread: "<<*value<<std::endl;
pthread_exit(NULL);
}
void *thread_2(void *arg)
{
int* value = new int(10);
std::cout<<"Value in thread: "<<*value<<std::endl;
pthread_exit(static_cast<void*>(value));
}
Try:
void *thread_1(void *arg)
{
int value = *((int *)arg);
cout<<"Value in thread: "<<value<<endl;
int new_val = 345;
pthread_exit(&new_val );
}
int main(int argc, char* argv[])
{
int *temp=15;
void *return_val;
pthread_t t1;
pthread_create(&t1, NULL,thread_1,(void *)temp);
pthread_join(t1,&return_val);
cout<<"Value in main: "<<*temp<<endl;
cout<<"Value from loop: "<<*(int*)return_val<<endl;
}
More info: http://www.cse.cuhk.edu.hk/~ericlo/teaching/os/lab/9-PThread/Pass.html

How to benchmark my system using multiple threads in c++?

I have simplified my code, and it compiles, but it doesn't do anything. It doesn't error out though either. I am trying to get 7 threads (on my 8-core processor) in this example to write to a variable to benchmark my system. I would like to do this with multiple threads to see if it's faster. It's based off other code that worked before I added multithreading. When I run, it just terminates. It should show progress each second of how many total iterations all the threads have done together. Some of the includes are there from other code I am working on.
I would like to also gracefully terminate all 7 threads when Ctrl-C is pressed. Help would be appreciated. Thanks!
//Compiled using: g++ ./test.cpp -lpthread -o ./test
#include <stdio.h>
#include <string>
#include <iostream>
#include <time.h>
#include <ctime>
#include <ratio>
#include <chrono>
#include <iomanip>
#include <locale.h>
#include <cstdlib>
#include <pthread.h>
using namespace std;
using namespace std::chrono;
const int NUM_THREADS = 7;
const std::string VALUE_TO_WRITE = "TEST";
unsigned long long int total_iterations = 0;
void * RunBenchmark(void * threadid);
class comma_numpunct: public std::numpunct < char > {
protected: virtual char do_thousands_sep() const {
return ',';
}
virtual std::string do_grouping() const {
return "\03";
}
};
void * RunBenchmark(void * threadid) {
unsigned long long int iterations = 0;
std::string benchmark;
int seconds = 0;
std::locale comma_locale(std::locale(), new comma_numpunct());
std::cout.imbue(comma_locale);
auto start = std::chrono::system_clock::now();
auto end = std::chrono::system_clock::now();
do {
start = std::chrono::system_clock::now();
while ((std::chrono::duration_cast < std::chrono::seconds > (end - start).count() != 1)) {
benchmark = VALUE_TO_WRITE;
iterations += 1;
}
total_iterations += iterations;
iterations = 0;
cout << "Total Iterations: " << std::setprecision(0) << std::fixed << total_iterations << "\r";
} while (1);
}
int main(int argc, char ** argv) {
unsigned long long int iterations = 0;
int tc, tn;
pthread_t threads[NUM_THREADS];
for (tn = 0; tn < NUM_THREADS; tn++) {
tc = pthread_create( & threads[tn], NULL, & RunBenchmark, NULL);
}
return 0;
}

How to convert a command line argument to an int?

Im trying to convert the command line argument(*argv[]) to an integer using the atoi function
int main(int argc, char *argv[]) {
This is my attempt
#include <iostream>
#include <sstream>
#include <string>
#include <cstdlib>
#include <conio.h>
using namespace std;
int main(int argc, char *argv[]) {
int x = 0;
for ( x=0; x < argc; x++ )
{
int x = atoi(argv[1]);
cout << x;
}
return 0;
}
However this returns 0 and im unsure why. Thankyou
It's hard to say having the arguments you pass to your program, but there are few problems here.
Your loop goes from 0 to argc, but your inside your loop you always use argv[1], if you didn't pass any arguments you're going out of bounds, because argv[0] is always the path to your executable.
atoi is a function from C, and when it fails to parse it's argument as an int, it returns 0, replace it with std::stoi, and you will get and execption if the conversion failed. You can catch this exception with try/catch, and then check the string that you tried to convert to int.
Well, this
#include <iostream>
#include <sstream>
#include <string>
#include <cstdlib>
#include <conio.h>
using namespace std;
int main(int argc, char* argv[]) {
int x = 0;
for (x = 0; x < argc; x++)
{
cout << argv[x];
}
return 0;
}
just prints the path to the .exe, the path is a string, it has no numbers. And as I understood from my "research" about command line arguments, you need to use your program through a command line, a terminal, to initialise the argv argument.
Link : https://www.tutorialspoint.com/cprogramming/c_command_line_arguments.htm
Also, as I understood at least, the argv[0] is always the path of the .exe
I hope I will be of some help, if I am mistaken at something, pls tell me where and I will correct my self by editing the answer