What is wrong with my thread program? - c++

I have the following code that is supposed to process ever wile with a .NEF extension.
#include <iostream>
#include <regex>
#include <pthread.h>
#include <dirent.h>
using namespace std;
void *workHorse(void*);
int main (int argc, char *argv[]){
pthread_t t1;
int rc, pos1;
DIR *dir;
struct dirent *ent;
regex e("(.*)(\\.)(NEF|nef)");
if ((dir = opendir (".")) != NULL) {
string fn1;
while ((ent = readdir (dir))!=NULL){
fn1.assign(ent->d_name);
if (regex_match ( fn1, e )){
cout<<"F :"<<fn1.c_str()<<" "<<endl;
if (rc=pthread_create( &t1, NULL, &workHorse, (void*)&fn1)){
cout<<"Error creating threads "<<rc<<endl;
exit(-1);
}
}
}
}
return 0;
}
void *workHorse(void *fileName){
int ret;
cout<<"W :"<<((string*)fileName)->c_str()<<endl;
pthread_exit(NULL);
}
There is just one file with .NEF extension in the directory. My expected output is -
F :DSC_0838.NEF
W :DSC_0838.NEF
However, I get
F :DSC_0838.NEF
W :RGBbmp.bmp
RGBbmp.bmp is another file in the same directory. What is wrong with my code? Why does it not work as expected?
The above code was compiled using -
g++ tmp.cpp -pthread --std=c++11

fn1's address is shared between the main thread and the secondary p_thread you create.
While the new thread is bootstrapping, the main thread changes the value in 'fn1' memory address, and the secondary thread reads the name of a different file (because in the main thread fn1 now has a new value).
You need to create a copy of the string you pass to the secondary thread, or you need to syncrhonize your read/write, I would recommend the former since it is way easier.
In this line:
if (rc=pthread_create( &t1, NULL, &workHorse, (void*)&fn1))
You are passing the address of fn1, the value then is changed in the main loop to some other file names, and by the time the tread comes up, it is now in RGBbmp.bmp

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.

error occur when I call execvp to run java

I use chdir() to switch the directory, and then use execvp() to execute "java Main". I'm sure there is Main.class, but something went wrong. I want to know why.
#include <cstdio>
#include <unistd.h>
using namespace std;
int main(){
char buf[80];
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
chdir("/home/keane/Judge/temp");
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
char *array[3];
array[0] = "java";
array[1] = "Main";
array[2] = NULL;
execvp("java", array);
return 0;
}
the error is could not find the main class , and I can run java Main in that directory.
What drives me crazy is that I can't use system("java Main"), and the error is that Error: Could not find or load main class Main, and it's just like this on my computer
update:
#include <unistd.h>
#include <cstdlib>
int main(){
chdir("/home/keane/Judge/temp");
system("pwd");
system("ls");
system("java Main");
return 0;
}
the output on console is:
/home/keane/Judge/temp
1.out 3.out 5.out Main.class stdout_spj.txt
2.out 4.out ce.txt Main.java
Error: Could not find or load the main class Main
my final solution is to reboot the computer and add -cp . to the java command.
althought I don't why is necessary.
thanks everyone!
This works as intended on my system, maybe you need to add -cp . to your java call.
EDIT: to elaborate: -cp (for classpath) tells java where to look for user provided .class files. This does not necessarily include the current working directory by default.
The execution of execvp() is non-blocking and takes ownership of the caller, that means that when it starts if the program ends too quickly you will never be able to see the result, to solve this I use fork(). The wait is just to avoid using sleep as I used at the begining. Its all in c.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char** argv){
char buf[80];
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
chdir("/home/");
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
char *array[3] = {"java", "Main", NULL};
if(fork() == 0) {
if(execvp("java", array) < 0) {
fprintf(stderr, "Error spawning command: %s\n", strerror(errno));
}
} else {
printf("Command spawned\n");
wait(NULL); // Wait to the forked process to end (avoid using sleep)
}
return 0;
}

Creating a c++ Program to execute other programs in qnx

I am trying to write a program in c++ for QNX which executes other programs.
For this I have 4 files to be handled.
file1
file2.l
file3.c
file4.bin
The algorithm is
if file1 is not present then execute file2.l
Execute file3.c
Execute file4.bin
This is the code which I have tried.
#include<fstream>
#include<iostrea>
using namespace std;
int main(){
ifstream ifile;
ifile.open("file1");
if(!ifile){
// system("Code to run file2.l program in termnal")
}
// system("Code to run file3.c program in termnal")
system("./file4.bin")
I need to know how to execute file2.l and file3.c using c++ in QNX
System() is only for executing system functions, such as 'cp' or 'shutdown'.
To launch a program, you can use spawn() or spawnv() functions.
#include <iostream>
using namespace std;
inline bool fileCheck(const string &name)
{
if (FILE *file = fopen(name.c_str(), "r"))
{
fclose(file);
return true;
}
else
{
return false;
}
}
int main(void)
{
// Replace with your own code
if (fileCheck("time.exe"))
{
// exists...
system("swap.exe");
}
else
{
// doesn't exists...
system("swap.exe");
}
return 0;
}
The program firstly creates an inline function to check the existence of a file in a fast way and then the main() occurs which does your required works.

implementation of asynchronous thread in c++

I am unable to find a correct usage of asynchronous thread in c++11.The thing i want to do is i want to spwan threads and each thread will function simultaneously without waiting for each other like thread.join(),which makes other thread to wait until the current thread is done with.So,is there any library in c++ which makes threads to run parallely doing their work simultaneously without having to wait for the other to complete.Actually the thing i want is i want to run each threads sumultaneously, so that they don't wait for the other to complete and its functionality is executed simultaneously without having to wait for others to finish .
Thanks,
Kushal
EDIT:
EDIT:: i am posting the code below
#include <signal.h>
#include <thread>
#include <algorithm>
#include <cstring>
#include <csignal>
#include "paho_client.h"
using namespace std;
vector<string> topic_container{"rpi2/temp","sense /bannana","sense/util","mqtt/temp","sense/temp","sense/pine","sense/fortis/udap"};
vector<paho_client> publisher;
vector<paho_client> subscriber;
int finish_thread=1;
void Onfinish(int signum){
finish_thread=0;
exit(EXIT_FAILURE);
}
int main(int argc, char** argv) {
signal(SIGINT, Onfinish);
int topic_index;
if(argc<3){
cout<<"the format of starting commandline argument is"<<endl;
exit(1);
}
while(finish_thread!=0){
//paho_client::get_library_handle();
if(strcmp(argv[1],"create_publisher")){
for(topic_index=0;topic_index<atoi(argv[2]);topic_index++){
thread pub_th;
pub_th = thread([ = ]() {
paho_client client("publisher", "192.168.0.102", "9876",
topic_container[topic_index].c_str());
client.paho_connect_withpub();
publisher.push_back(client);
});
pub_th.join();
}
vector<paho_client>::iterator it;
int publisher_traverse=0;
for(it=publisher.begin();it<publisher.end();publisher_traverse++){
publisher[publisher_traverse].increment_count();
publisher[publisher_traverse].get_count();
}
}
}
return 0;
}
After using async with future am getting the same behaviour as above please point me where am i going wrong
#include <signal.h>
#include <thread>
#include <algorithm>
#include <cstring>
#include <csignal>
#include <future>
#include "paho_client.h"
using namespace std;
vector<string> topic_container{"rpi2/temp","sense/apple","sense/bannana","sense/util","mqtt/temp","sense/temp","sense/pine","sense/fortis/udap"};
vector<paho_client> publisher;
vector<paho_client> subscriber;
int finish_thread=1;
void Onfinish(int signum){
finish_thread=0;
exit(EXIT_FAILURE);
}
int accumulate_block_worker_ret(int topic_index) {
//int topic_index=0;
paho_client client("publisher", "192.168.0.102", "9876",
topic_container[topic_index].c_str());
client.paho_connect_withpub();
publisher.push_back(client);
client.increment_count();
return client.get_count();
}
int main(int argc, char** argv) {
signal(SIGINT, Onfinish);
if(argc<3){
cout<<"the format of starting commandline argument is . /paho_client_emulate <create_publisher><count of publisher client to spawn>" <<endl;
exit(1);
}
while(finish_thread!=0){
// paho_client::get_library_handle();
int topic_index;
if(strcmp(argv[1],"create_publisher")){
for(topic_index=0;topic_index<atoi(argv[2]);topic_index++){
// thread pub_th;
// pub_th = thread([ = ]() {
future<int> f = async(std::launch::async,accumulate_block_worker_ret,topic_index);
// });
// pub_th.join();
cout<<"the returned value from future is"<<f.get()<<endl;
}
vector<paho_client>::iterator it;
int publisher_traverse=0;
for(it=publisher.begin();it<=publisher.end();publisher_traverse++){
cout<<"came here"<<endl;
publisher[publisher_traverse].increment_count();
publisher[publisher_traverse].get_count();
}
}
}
return 0;
}
i want to launch all the publisher clients first (as threads) and
later publish messages from each threads
The pub_th.join() is misplaced inside the loop where the threads are started, thus waiting for the termination of each thread before starting the next one. To let the threads run in parallel, just move the .join() outside that loop. Of course to access the threads after the loop body, they have to be stored somewhere, e. g. in a vector - for this, change the first for loop to
vector <thread> pub_threads;
for (topic_index=0; topic_index<atoi(argv[2]); topic_index++)
{
pub_threads.push_back(thread([ = ]() { /* whatever */ }));
}
and later when done:
for (auto &th: pub_threads) th.join();
Actually i am running infinite while inside every instance of
paho_client so the first thread is not completed …
that thread is run continously
Of course if never done, there's no point to .join().

Cannot compile demo program using fork() and pipes() in C++

All, the first part of my homework assignment is simply a demo program that I need to compile, and then modify. It was provided by the teacher, however I simply cannot get it to compile using g++. I will be creating a make file at the end of the assignment, but for the moment I am simply trying to test it out, and am having no luck. I've tried the most basic g++ command: g++ -o main TwoPipesTwoChildren.cpp . Can someone please help? I can't even get started on this until I can get this working.
// description: This program will execute "ls -ltr | grep 3376"
// by using a parent and child process
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char **argv){
printf("TEST");
int status;
int childpid;
char *cat_args[] = {"ls", "-ltr", NULL};
char *grep_args[] = {"grep", "3376", NULL};
// create one pipe to send the output of "ls" process to "grep" process
int pipes[2];
pipe(pipes);
// fork the first child (to execute cat)
if((childpid = fork()) == -1)
{
perror("Error creating a child process");
exit(1);
}
// replace cat's stdout with write part of 1st pipe
if (childpid == 0)
{
dup2(pipes[1], 1);
printf("AFTER FORK CHILD");
//close all pipes (very important!); end we're using was safely copied
close(pipes[0]);
close(pipes[1]);
execvp(*cat_args, cat_args);
exit(0);
}
else
{
// replace grep's stdin with read end of 1st pipe
dup2(pipes[0], 0);
close(pipes[0]);
close(pipes[1]);
execvp(*grep_args, grep_args);
}
return (0);
}