I have 2 threads.
My goal is that the first one that terminate his own execution, have to stop the other thread.
Is it possible?
I have this code:
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
void* start1(void* arg)
{
printf("I'm just born 1\n");
int i = 0;
for (i = 0;i < 100;i++)
{
printf("Thread 1\n");
}
printf("I'm dead 1\n");
pthread_exit(0);
}
void* start2(void* arg)
{
printf("I'm just born 2\n");
int i = 0;
for (i = 0;i < 1000;i++)
{
printf("Thread 2\n");
}
printf("I'm dead 2\n");
pthread_exit(0);
}
void* function()
{
int k = 0;
int i = 0;
for (i = 0;i < 50;i++)
{
k++;
printf("I'm an useless function\n");
}
}
int main()
{
pthread_t t, tt;
int status;
if (pthread_create(&t, NULL, start1, NULL) != 0)
{
printf("Error creating a new thread 1\n");
exit(1);
}
if (pthread_create(&tt, NULL, start2, NULL) != 0)
{
printf("Error creating a new thread 2\n");
exit(1);
}
function();
pthread_join(t, NULL);
pthread_join(tt, NULL);
return 0;
}
For example the first thread have to stop the second one.
How can is possible to do that?
Generally it's not good practice to force a thread to terminate. The clean way to terminate another thread is by setting a flag (visible to both threads) that tells the thread to terminate itself (by returning/exiting immediately).
This sounds like very complex (bad) design. Usually you would have a master (controller) and it would have children.
If you must take this approach I would make the first thread spawn the second, then the second the thrid (so that it "owns" that thread).
Finally if you must do it this way you can pass the thread to the first worker by it's void* argument.
Also you do not need to explicitly exit the thread, just let it 'run off' then join it.
Pass as arguments to the 2 threads the thread id of the other. Than call pthread_kill(other_thread_id, SIGKILL) in the first that finishes his work. I assume you know what you are doing (you've already been warned that this is bad practice).
See the method pthread_cancel() to cancel (end) a thread.
Related
I have a function that is not the main function, A. This function simply iterates, say 1 to 1,000,000. At every X iteration, lets say 10,000, I want to run another function, but not stop the iteration. So it'd look something like this:
void iterate() {
for (int i = 0; i < 1000000; i++) {
i++;
if ((i%10000) == 0) {
// Spawn a process here
// This process should start, then
// the rest of the iterations should continue
// while the process is running
}
}
}
How would I do it?
This should work on POSIX compliant systems or using Cygwin on Windows.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
void func(void)
{
printf("Fork called\n");
}
void iterate(void)
{
pid_t pid;
int i;
for (i = 0; i < 1000000; i++) {
if (!(i % 10000)) {
pid = fork();
if (!pid) {
func();
exit(0);
}
}
}
wait(NULL);
}
int main(void)
{
iterate();
return 0;
}
fork() will start a child process. After the fork make you check that you are a child process and execute whatever you want. The wait() after the for loop will pause the parent process until the all sub processes finish executing.
Additional info about fork() and wait():
https://www.man7.org/linux/man-pages/man2/fork.2.html
https://www.man7.org/linux/man-pages/man2/wait.2.html
I am trying to implement the Producer-Consumer problem operating system using semaphore and pthread. But my output is totally different from expected. Here is my code:
#include<iostream>
#include<pthread.h>
#include<fstream>
#include<unistd.h>
#include<queue>
// define queue size
#define QUEUE_SIZE 5
// declare and initialize semaphore and read/write counter
static int semaphore = 1;
static int counter = 0;
// Queue for saving characters
static std::queue<char> charQueue;
// indicator for end of file
static bool endOfFile = false;
// save arrays
char consumerArray1[100];
char consumerArray2[100];
// function to wait for semaphore
void wait()
{
while(semaphore<=0);
semaphore--;
}
// function to signal the wait function
void signal()
{
semaphore++;
}
void *Producer(void *ptr)
{
int i=0;
std::ifstream input("string.txt");
char temp;
while(input>>temp)
{
wait();
charQueue.push(temp);
//std::cout<<"Producer:\nCounter: "<<counter<<" Semaphore: "<<semaphore<<std::endl;
counter++;
std::cout<<"Procuder Index: "<<i<<std::endl;
i++;
signal();
sleep(2);
}
endOfFile = true;
pthread_exit(NULL);
}
void *Consumer1(void *ptr)
{
std::cout<<"Entered consumer 1:"<<std::endl;
int i = 0;
while(counter<=0);
while(!endOfFile)
{
while(counter<=0);
wait();
//std::cout<<"Consumer1:\nCounter: "<<counter<<" Semaphore: "<<semaphore<<std::endl;
consumerArray1[i] = charQueue.front();
charQueue.pop();
i++;
counter--;
std::cout<<"Consumer1 index:"<<i<<" char: "<<consumerArray1[i]<<std::endl;
signal();
sleep(2);
}
consumerArray1[i] = '\0';
pthread_exit(NULL);
}
void *Consumer2(void *ptr)
{
std::cout<<"Entered consumer 2:"<<std::endl;
int i = 0;
while(counter<=0);
while(!endOfFile)
{
while(counter<=0);
wait();
//std::cout<<"Consumer2:\nCounter: "<<counter<<" Semaphore: "<<semaphore<<std::endl;
consumerArray2[i] = charQueue.front();
charQueue.pop();
i++;
counter--;
std::cout<<"Consumer2 index: "<<i<<" char: "<<consumerArray2[i]<<std::endl;
signal();
sleep(4);
}
consumerArray2[i] = '\0';
pthread_exit(NULL);
}
int main()
{
pthread_t thread[3];
pthread_create(&thread[0],NULL,Producer,NULL);
int rc = pthread_create(&thread[1],NULL,Consumer1,NULL);
if(rc)
{
std::cout<<"Thread not created"<<std::endl;
}
pthread_create(&thread[2],NULL,Consumer2,NULL);
pthread_join(thread[0],NULL);pthread_join(thread[1],NULL);pthread_join(thread[2],NULL);
std::cout<<"First array: "<<consumerArray1<<std::endl;
std::cout<<"Second array: "<<consumerArray2<<std::endl;
pthread_exit(NULL);
}
The problem is my code, in some runs freezes(probably in an infinite loop) after the entire file has been read. And also both of the consumer functions read the same words even though I am popping it out after reading. Also the part of printing the array element that has been read just prints blank. Why are these problems happening? I am new to threads(as in coding using threads, I know theoretical concepts of threads) so please help me with this problem.
The pthreads standard prohibits accessing an object in one thread while another thread is, or might be, modifying it. Your wait and signal functions violate this rule by modifying semaphore (in signal) while a thread calling wait might be accessing it. You do this with counter as well.
If what you were doing in signal and wait were legal, you wouldn't need signal and wait. You could just access the queue directly the same way you access semaphore directly. If the queue needs protection (as I hope you know it does) then semaphore needs protection too and for exactly the same reason.
The compiler is permitted to optimize this code:
while(semaphore<=0);
To this code:
if (semaphore<=0) { while (1); }
Why? Because it knows that no other thread can possibly modify semaphore while this thread could be accessing it since that is prohibited by the standard. Therefore, there is no reason to read more than once.
You need to use actual sempahores and/or locks.
I am new to multi-threaded programming and I am following this tutorial. In the tutorial, there is a simple example showing how to use pthread_create() and pthread_join(). My question: why can we not put pthread_join() in the same loop as pthread_create()?
Code for reference:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 2
/* create thread argument struct for thr_func() */
typedef struct _thread_data_t {
int tid;
double stuff;
} thread_data_t;
/* thread function */
void *thr_func(void *arg) {
thread_data_t *data = (thread_data_t *)arg;
printf("hello from thr_func, thread id: %d\n", data->tid);
pthread_exit(NULL);
}
int main(int argc, char **argv) {
pthread_t thr[NUM_THREADS];
int i, rc;
/* create a thread_data_t argument array */
thread_data_t thr_data[NUM_THREADS];
/* create threads */
for (i = 0; i < NUM_THREADS; ++i) {
thr_data[i].tid = i;
if ((rc = pthread_create(&thr[i], NULL, thr_func, &thr_data[i]))) {
fprintf(stderr, "error: pthread_create, rc: %d\n", rc);
return EXIT_FAILURE;
}
}
/* block until all threads complete */
for (i = 0; i < NUM_THREADS; ++i) {
pthread_join(thr[i], NULL);
}
return EXIT_SUCCESS;
}
I figured it out. For other users with same question, I am writing below the answer.
If we put the pthread_join() in the same loop with pthread_create(), the calling thread i.e. main() will wait for the thread 0 to finish its work before creating the thread 1. This would force the threads to execute sequentially, not in parallel. Thus it would kill the purpose of multi-threading.
I'm creating 9 threads using something like this (all threads will process infinity loop)
void printStr();
thread func_thread(printStr);
void printStr() {
while (true) {
cout << "1\n";
this_thread::sleep_for(chrono::seconds(1));
}
}
I also create 10th thread to control them. How would I stop or kill any of this 9 threads from my 10th? Or suggest another mechanism please.
You can use, for example, atomic boolean:
#include <thread>
#include <iostream>
#include <vector>
#include <atomic>
using namespace std;
std::atomic<bool> run(true);
void foo()
{
while(run.load(memory_order_relaxed))
{
cout << "foo" << endl;
this_thread::sleep_for(chrono::seconds(1));
}
}
int main()
{
vector<thread> v;
for(int i = 0; i < 9; ++i)
v.push_back(std::thread(foo));
run.store(false, memory_order_relaxed);
for(auto& th : v)
th.join();
return 0;
}
EDIT (in response of your comment): you can also use a mutual variable, protected by a mutex.
#include <thread>
#include <iostream>
#include <vector>
#include <mutex>
using namespace std;
void foo(mutex& m, bool& b)
{
while(1)
{
cout << "foo" << endl;
this_thread::sleep_for(chrono::seconds(1));
lock_guard<mutex> l(m);
if(!b)
break;
}
}
void bar(mutex& m, bool& b)
{
lock_guard<mutex> l(m);
b = false;
}
int main()
{
vector<thread> v;
bool b = true;
mutex m;
for(int i = 0; i < 9; ++i)
v.push_back(thread(foo, ref(m), ref(b)));
v.push_back(thread(bar, ref(m), ref(b)));
for(auto& th : v)
th.join();
return 0;
}
It is never appropriate to kill a thread directly, you should instead send a signal to the thread to tell it to stop by itself. This will allow it to clean up and finish properly.
The mechanism you use is up to you and depends on the situation. It can be an event or a state checked periodically from within the thread.
std::thread objects are non - interruptible. You will have to use another thread library like boost or pthreads to accomplish your task. Please do note that killing threads is dangerous operation.
To illustrate how to approach this problem in pthread using cond_wait and cond_signal,In the main section you could create another thread called monitor thread that will keep waiting on a signal from one of the 9 thread.
pthread_mutex_t monMutex;////mutex
pthread_cond_t condMon;////condition variable
Creating threads:
pthread_t *threads = (pthread_t*) malloc (9* sizeof(pthread_t));
for (int t=0; t < 9;t++)
{
argPtr[t].threadId=t;
KillAll=false;
rc = pthread_create(&threads[t], NULL, &(launchInThread), (void *)&argPtr[t]);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
creating monitor thread:
monitorThreadarg.threadArray=threads;//pass reference of thread array to monitor thread
monitorThreadarg.count=9;
pthread_t monitor_thread;
rc= pthread_create(&monitor_thread,NULL,&monitorHadle,(void * )(&monitorThreadArg));
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
then wait on 9 threads and monitor thread:
for (s=0; s < 9;s++)
{
pthread_join(threads[s], &status);
}
pthread_cond_signal(&condMon);// if all threads finished successfully then signal monitor thread too
pthread_join(monitor_thread, &status);
cout << "joined with monitor thread"<<endl;
The monitor function would be something like this:
void* monitorHadle(void* threadArray)
{
pthread_t* temp =static_cast<monitorThreadArg*> (threadArray)->threadArray;
int number =static_cast<monitorThreadArg*> (threadArray)->count;
pthread_mutex_lock(&monMutex);
mFlag=1;//check so that monitor threads has initialised
pthread_cond_wait(&condMon,&monMutex);// wait for signal
pthread_mutex_unlock(&monMutex);
void * status;
if (KillAll==true)
{
printf("kill all \n");
for (int i=0;i<number;i++)
{
pthread_cancel(temp[i]);
}
}
}
the function what will be launched over 9 threads should be something like this:
void launchInThread( void *data)
{
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
while(1)
{
try
{
throw("exception whenever your criteria is met");
}
catch (string x)
{
cout << "exception form !! "<< pthread_self() <<endl;
KillAll=true;
while(!mFlag);//wait till monitor thread has initialised
pthread_mutex_lock(&monMutex);
pthread_cond_signal(&condMon);//signail monitor thread
pthread_mutex_unlock(&monMutex);
pthread_exit((void*) 0);
}
}
}
Please note that if you dont't put :
thread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
after launching your thread then your threads wouldn't terminate on thread_cancel call.
It is necessary that you clean up up all the data before you cancel a thread.
Example:
void start(void)
{
pthread_create(&threadID, Null, run_thread_function,arguments);
//is there a way to ensure if the run_thread_function(basically new thread) started
//execution before returning from this(start) function
}
Check the return code.
if ((retcode = pthread_create(&threadID, Null, run_thread_function,arguments)) != 0)
{
//something went wrong
}
Pass a synchro object, (condvar, event or semaphore), as part of the arguments. Wait on it after calling pthread_create(). In the thread, signal it in the first line, (or after the thread has performed its init stuff, if that's what you are trying to achieve).
Check the return code of the pthread_create function for error.
Update some shared variable and test it from another thread. Remember to use synchronization primitives, like mutex when updating the shared variable.
Or to make simple test, print some message with the thread id, or some other kind of identifier.
With C++11, creating a thread through an object of type std::thread won't return until the new thread has started.
Use pthread_barrier_wait if you want to know for certain that your new thread has begun.
Though, I really question code that cares deeply about this. Seems like you're asking for race conditions.
Note that I should be checking for return values all over the place and I'm not for the sake of succinctness clarity. sigh
#include <iostream>
#include <pthread.h>
#include <unistd.h>
void *newthread(void *vbarrier)
{
pthread_barrier_t *barrier = static_cast<pthread_barrier_t *>(vbarrier);
sleep(2);
int err = pthread_barrier_wait(barrier);
if ((err != 0) && (err != PTHREAD_BARRIER_SERIAL_THREAD)) {
::std::cerr << "Aiee! pthread_barrier_wait returned some sort of error!\n";
} else {
::std::cerr << "I am the new thread!\n";
}
return 0;
}
int main()
{
pthread_barrier_t barrier;
pthread_barrier_init(&barrier, NULL, 2);
pthread_t other;
pthread_create(&other, NULL, newthread, &barrier);
pthread_barrier_wait(&barrier);
::std::cerr << "Both I and the new thread reached the barrier.\n";
pthread_join(other, NULL);
return 0;
}
C++11 doesn't have barriers. But barriers can easily be simulated, to an extent, using condition variables:
#include <thread>
#include <condition_variable>
#include <iostream>
#include <unistd.h>
void runthread(::std::mutex &m, ::std::condition_variable &v, bool &started)
{
sleep(2);
{
::std::unique_lock< ::std::mutex> lock(m);
started = true;
v.notify_one();
}
::std::cerr << "I am the new thread!\n";
}
int main()
{
::std::mutex m;
::std::condition_variable v;
bool started = false;
::std::thread newthread(runthread, ::std::ref(m), ::std::ref(v), ::std::ref(started));
{
::std::unique_lock< ::std::mutex> lock(m);
while (!started) {
v.wait(lock);
}
}
::std::cerr << "Both I and the new thread are running.\n";
newthread.join();
return 0;
}