I need a thread that will call continuously in while(1), but when i use to call thread function by pthread_create() a new thread creates.
I need help on following points :~
1) Is there any method to call thread function without creating thread.
2) Is there any method to destroy the previous thread.
Sample code is
void main()
{
pthread_t thread1;
while(1)
{
pthread_create( &thread1, NULL, myFun, (void*) NULL);
}
}
void * myFun(void *ptr)
{
printf("Hello");
}
* We can not create more than 380 threads, Here we have to use only single thread.
um, I think what you really want to do is like that:
bool received_data = false;
bool beExit = false;
struct recvPacket;
pthread_mutex_t recvMutex;
void main()
{
pthread_t thread1;
void *status;
pthread_mutex_init(&recvMutex, NULL);
pthread_create(&thread1, NULL, myFun, (void*) NULL);
while(1)
{
if (received_data) {
pthread_mutex_lock(&recvMutex); // you should also synchronize received_data and beExit valuables, cuz they are shared by two threads
/* do what you want with recvPacket */
pthread_mutex_unlock(&recvMutex);
received_data == false;
}
/* do else you want, or you can let beExit = true to stop the thread */
}
if (err = pthread_join(thr_main, &status))
printf("pthread_join Error. %s\n", strerror(err)), exit(1);
}
void * myFun(void *ptr)
{
while (!beExit) {
if (true == tryRecvPacket()) {
pthread_mutex_lock(&recvMutex);
/* fill data to recvPacket */
pthread_mutex_unlock(&recvMutex);
received_data = true;
}
}
}
Suggested design is.
void * myFun(void *ptr);
volatile int thread_exit = 1;
void main()
{
pthread_t thread1;
pthread_create( &thread1, NULL, myFun, (void*) NULL);
while(1)
{
//Ask every 10 sec for killing thread like
sleep(10);
printf("Do you wish to kill [0/1]???");
scanf("%d", &thread_exit);
}
//Add code here to make main() to wait till thread dies.
//pthread_join(&thread1);
}
void * myFun(void *ptr)
{
while(thread_exit)
{
printf("Hello");
}
}
For destroying the thread, you can use pthread_kill function available
int pthread_kill(pthread_t thread, int sig);
But its not good practice to kill the thread forcefully as it might cause the problem of the memory leak.
When the parent thread is finished, then all the child threads are finished abruptly.
In your example, as child thread will be in the infinite loop so child thread never finishes. But parent thread-main thread will finish after executing the return 0 statement. So main thread will terminate the child thread also.
To overcome this situation i.e. wait until all child threads have finished, pthread_join(thread1) method is there. So the thread calling this function will wait unless thread1 has finished.
Thanks to all for quick reply..
Problem has been fixed by using following code.
setsockopt (socket_desc, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,sizeof(timeout));
Here i set the timeout for accept the tcp clients request in microseconds.. now code is working OK.
Related
I am writing a c program to create three threads(1,2,3) such that at any given point of time only one thread must execute and print the output on console in the order 123123123123.........
I am making use of semaphore for synchronization.
I am having an issue with the code i have written. the code doesn't print it in the order 123123... the order is random and stops after a while.
#include<stdio.h>
#include<semaphore.h>
#include<pthread.h>
#include<unistd.h>
#include<assert.h>
#include<stdlib.h>
sem_t sem_1;
void *func1(void *arg){
int err1=0;
while(1){
err1=sem_wait(&sem_1);
assert(err1==0);
printf("thread 1\n");
}
//return NULL;
}
void *func2(void *arg){
int err2=0;
while(1){
err2=sem_wait(&sem_1);
assert(err2==0);
printf("thread 2\n");
}
// return NULL;
}
void *func3(void *arg){
int err3=0;
while(1){
err3=sem_wait(&sem_1);
assert(err3==0);
printf("thread 3\n");
}
// return NULL;
}
int main(){
pthread_t *t1,*t2,*t3;
int i=0,rc=0,c1=0,c2=0,c3=0;
t1=(pthread_t *)malloc(sizeof(*t1));
t2=(pthread_t *)malloc(sizeof(*t2));
t3=(pthread_t *)malloc(sizeof(*t3));
i=sem_init(&sem_1,0,1);
assert(i==0);
c1=pthread_create(t1,NULL,func1,NULL);
assert(c1==0);
c2=pthread_create(t2,NULL,func2,NULL);
assert(c2==0);
c3=pthread_create(t3,NULL,func3,NULL);
assert(c3==0);
while(1){
rc=sem_post(&sem_1);
assert(rc==0);
sleep(1);
}
return 0;
}
Why would you even expect them in in an order?
Your threads do things inbetween the different waits, and according to the system scheduler, these can take different amount of time.
printf is a buffered operation that gives you exclusive access to a shared resource. So in addition to your semaphore there is a hidden lock somewhere, that also regulates the progress of your threads. Don't expect the prints to appear in order, even if the calls themselves are.
Then, for the end, using assert here is really a very bad idea. All sem_t operations can (and will) fail spuriously, so it is really bad to abort, just because such a failure.
In fact, sem_t is really a low level tool, and you should never use it without checking return values and without having a fall back strategy if such a call fails.
Of course. I can't see any order related synchronization mechanism.
One of the options to achieve the strict order is to have one semaphore per thread:
sem_t sem[3];
// ...
while(1) {
for(n = 0; n < 3; n++) {
rc=sem_post(&sem[n]);
assert(rc==0);
}
sleep(1);
}
Below Code will help to solve the problem, one semaphore for each thread used to achieve synchronization. The initial value of the semaphore does the job. used usleep to launch thread in sequence manner for needed output. The same can be done by using Mutex lock and cond variables
//declaring semaphore
sem_t sema1;
sem_t sema2;
sem_t sema3;
void* t1(void *arg)
{
for(int j=0;j<10;j++)
{
sem_wait(&sema1);
printf("Thread 1 \n");
sem_post(&sema2);
}
printf("T1 return\n");
return NULL;
}
void* t2(void *arg)
{
for(int j=0;j<10;j++)
{
sem_wait(&sema2);
printf("Thread 2 \n");
sem_post(&sema3);
}
printf("T2 return\n");
return NULL;
}
void* t3(void *arg)
{
for(int j=0;j<10;j++)
{
sem_wait(&sema3);
printf("Thread 3 \n");
sem_post(&sema1);
}
printf("T3 return \n");
return NULL;
}
int main()
{
pthread_t tid1, tid2,tid3;
sem_init(&sema1,0,1);
sem_init(&sema2,0,0);
sem_init(&sema3,0,0);
pthread_create(&tid1, NULL, t1, NULL);
usleep(100);
pthread_create(&tid2, NULL, t2, NULL);
usleep(100);
pthread_create(&tid3, NULL, t3, NULL);
pthread_join(tid3, NULL);
pthread_join(tid2, NULL);
pthread_join(tid1, NULL);
sem_destroy(&sema1);
sem_destroy(&sema2);
sem_destroy(&sema3);
return 0;
}
I have a worker thread doing a polling activity (it's targeting libcurl but that is not relevant).
Many actions from the application can start a worker thread but if it is already running, no new thread should be created. A new request from the application is simply joined with any other polling already ongoing.
In summary, a single worker thread that exits when there is nothing left to do.
The code is:
pthread_t thread = NULL;
struct timespec sleep_val = {0, 20000000};
void *worker_thread(void *threadid)
{
do {
poll();
nanosleep(&sleep_val, NULL);
} while (no_of_handles_running > 0);
pthread_exit(NULL);
thread = NULL;
}
void start_worker_thread_if_needed() {
if (thread == NULL) {
pthread_create(&thread, NULL, worker_thread, NULL);
}
}
My doubt is about thread safety. The function start_worker_thread_if_needed() can be called at any time any number of times.
So, what if start_worker_thread_if_needed() is called exactly when we exit the while loop and therefor interrupts the worker thread. If that happens the condition if (thread == NULL) will be FALSE since the worker thread is interrupted and pthread_exit + thread = NULL has not yet completed.
So now start_worker_thread_if_needed() will exit without creating a new thread but as soon as control is returned to the old worker thread it will continue to the pthread_exit line and the worker thread is destroyed.
The issue will be that the request that was just made triggering start_worker_thread_if_needed() will be lost and the polling will not start until the next call to start_worker_thread_if_needed().
Edit: Here is a suggestion with mutex but I still have the same doubt. What happens if the main thread interrupts just after we exit the while loop and before the worker can take the mutex. Then the main thread does not create a new thread and then the worker exit.
void *worker_thread(void *threadid)
{
do {
poll();
nanosleep(&sleep_val, NULL);
} while (no_of_handles_running > 0);
pthread_mutex_lock(&my_mutex);
thread = NULL;
pthread_mutex_unlock(&my_mutex);
pthread_exit(NULL);
}
void start_worker_thread_if_needed() {
pthread_mutex_lock(&my_mutex);
if (thread == NULL) {
pthread_create(&thread, NULL, worker_thread, NULL);
}
pthread_mutex_unlock(&my_mutex);
}
I think I have a flaw in how I have set this up and it would be highly appreciated if someone could help out with the proper solution.
Thanks to for all the help in the comments above. Kaylums suggestion to use condition variables seems to be a good approach to not risk ending up with the corner case I was concerned about.
The final code (with logs removed) is the one below and it appears to work just fine.
static int no_of_handles_running;
static int RUN_THREAD = 0;
pthread_t thread = NULL;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;;
void *worker_thread(void *threadid)
{
RUN_THREAD = 1;
do {
poll(); //Will update no_of_handles_running
if (no_of_handles_running == 0) {
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cv, &mutex);
pthread_mutex_unlock(&mutex);
}
} while (RUN_THREAD);
thread = NULL;
pthread_exit(NULL);
}
void start_worker_thread() {
if (thread == NULL) {
int rc = pthread_create(&thread, NULL, worker_thread, NULL);
if (rc){
return;
}
}
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cv);
pthread_mutex_unlock(&mutex);
}
void stop_worker_thread() {
RUN_THREAD = 0;
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cv);
pthread_mutex_unlock(&mutex);
}
This code worked fine , but how to use it to kill for array of remaining threads?
#include<stdio.h>
#include<signal.h>
#include<pthread.h>
void *print1(void *tid)
{
pthread_t *td= tid;
pthread_mutex_t lock1=PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&lock1);
printf("1");
printf("2");
printf("3");
printf("4\n");
printf("Coming out of thread1 \n");
sleep(2);
pthread_mutex_unlock(&lock1);
pthread_kill(*td,SIGKILL);//killing remaining all threads
return NULL;
}
void *print2(void *arg)
{
pthread_mutex_t *lock = arg;
pthread_mutex_lock(lock);
sleep(5);
printf("5");
sleep(5);
printf("6");
sleep(5);
printf("7");
sleep(5);
printf("8\n");
fflush(stdout);
pthread_mutex_unlock(lock);
return NULL;
}
int main()
{
int s;
pthread_t tid1, tid2;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
printf("creating Thread 1and 2 \n");
sleep(2);
pthread_create(&tid1, NULL, print1,&tid2);
pthread_create(&tid2, NULL, print2,&lock);
printf("Running Thread 1\n");
sleep(2);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
Comments: Please delete this and add some extra information about the code. The editor is not allowing me to edit the code.
here is an edited version of the code
along with some commentary
#include<signal.h>
#include<pthread.h>
void *print1(void *tid)
{
// should be in global space, so no need to pass
pthread_t *td= tid;
// this is a whole new mutex,
//should be in global space so other threads can access it
pthread_mutex_t lock1=PTHREAD_MUTEX_INITIALIZER;
// why bother with the mutex, it does nothing useful
pthread_mutex_lock(&lock1);
printf("1");
printf("2");
printf("3");
printf("4\n");
printf("Coming out of thread1 \n");
sleep(2);
pthread_mutex_unlock(&lock1);
pthread_kill(*td,SIGKILL);//killing remaining all threads return NULL;
// this exit is not correct, it should be this call:
// void pthread_exit(void *rval_ptr);
} // end function: print1
void *print2(void *arg)
{
// this should be in global memory so all threads using same mutex
pthread_mutex_t *lock = arg;
pthread_mutex_lock(lock);
sleep(5);
printf("5");
sleep(5);
printf("6");
sleep(5);
printf("7");
sleep(5);
printf("8\n");
fflush(stdout);
pthread_mutex_unlock(lock);
// this exit is not correct, it should be this call:
// void pthread_exit(void *rval_ptr);
return NULL;
} // end function: print2
int main()
{
int s;
// this should be in global memory
// so no need to pass to threads
pthread_t tid1, tid2;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
printf("creating Thread 1and 2 \n");
// why bother to sleep here?
sleep(2);
// in these calls, the last parm should be NULL
// and the related data should be in global memory
pthread_create(&tid1, NULL, print1,&tid2);
pthread_create(&tid2, NULL, print2,&lock);
// we are still in main, so this printf is misleading
printf("Running Thread 1\n");
// no need to sleep()
// as the pthread_join calls will wait for the related thread to exit
sleep(2);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
} // end function: main
However you want. There is no "one right way" to do this.
Probably the easiest way is to replace your calls to sleep with calls to a function that uses pthread_cond_timedwait and a predicate that causes the thread to call pthread_exit.
In psuedo-code, replace calls to sleep with this logic:
Compute the time to sleep until.
Lock the mutex.
Check if the predicate is set to exit, if so, call pthread_exit.
Call pthread_cond_timedwait.
Check if the predicate is set to exit, if so, call pthread_exit.
Check if the time expired, if not, go to stop 4.
And to terminate the threads, do this:
Lock the mutex.
Set the predicate to exit.
Call pthread_cond_broadcast.
Release the mutex.
Call pthread_join on the threads to wait until they've terminated.
I have a program that creates two worker threads like the following:
void *Producer(void *threadarg){
while (!terminate_producer){ //do something}
printf("Producer: finalizing thread\n");
pthread_exit(NULL);
}
void *Consumer(void *threadarg){
while (!terminate_consumer){ //do something}
printf("Consumer: finalizing thread\n");
pthread_exit(NULL);
}
// Initialize array of the worker threads
void initFuncArray(long result[])
{
result[0] = (long)&Producer;
result[1] = (long)&Consumer;
}
// The main method
int main (int argc, char* argv[]){
long th_funcs[CPUS_NUM];
initFuncArray(th_funcs);
// threads data
pthread_t tid[CPUS_NUM];
thread_data prod_th_data[CPUS_NUM];
bool pt = false;
for (int i=0;i<CPUS_NUM;i++){
prod_th_data[i].thread_id = i;
pt = pthread_create(&tid[i], NULL, (void *)th_funcs[i], (void*)&prod_th_data[i]);
if (pt) return -1;
}
sleep(5);
terminate_producer = true;
pthread_join (tid[0], NULL);
**sleep(1);**
terminate_consumer = true;
pthread_join (tid[1], NULL);
// Exiting the main thread
return 0;
}
My question is about a call to sleep before terminating the consumer thread. If I do not have this call, the program terminates normally. However, if I have that sleep, the program never terminates. I see the message that the producer thread terminates, but I do not get the message from the consumer thread. What might be the problem?
Following suggestions I modified the code as follows, however, the problem now appears even without a call to sleep in-between:
typedef void (*func_type) (void *);
pthread_mutex_t terminate_producer;
pthread_mutex_t terminate_consumer;
void *Producer(void *threadarg){
while (pthread_mutex_trylock(&terminate_producer)){ //do something}
printf("Producer: finalizing thread\n");
pthread_mutex_unlock(&terminate_producer);
return NULL;
}
void *Consumer(void *threadarg){
while (pthread_mutex_trylock(&terminate_consumer))
printf("Consumer: finalizing thread\n");
pthread_mutex_unlock(&terminate_consumer);
return NULL;
}
// Initialize array of the worker threads
void initFuncArray(func_type result[])
{
result[0] = Producer;
result[1] = Consumer;
}
// The main method
int main (int argc, char* argv[]){
func_type th_funcs[CPUS_NUM];
initFuncArray(th_funcs);
// threads data
pthread_t tid[CPUS_NUM];
thread_data prod_th_data[CPUS_NUM];
// Using mutexes as termination condition
pthread_mutex_init(&terminate_producer,NULL);
pthread_mutex_init(&terminate_consumer,NULL);
pthread_mutex_lock(&terminate_producer);
pthread_mutex_lock(&terminate_consumer);
bool pt = false;
for (int i=0;i<CPUS_NUM;i++){
prod_th_data[i].thread_id = i;
pt = pthread_create(&tid[i], NULL, (void *)th_funcs[i], (void*)&prod_th_data[i]);
if (pt) return -1;
}
sleep(5);
pthread_mutex_unlock(&terminate_producer);
pthread_join (tid[0], NULL);
pthread_mutex_unlock(&terminate_consumer);
pthread_join (tid[1], NULL);
// Exiting the main thread
return 0;
}
Flag terminate_producer represents a critical section. Producers are reading its value and main thread is rewriting it at the same time. Access to this flag should be protected with some synchronization mechanism such as mutex:
inline stopProducers() {
/* GET LOCK */
terminate_producer = 1;
/* RELEASE LOCK */
}
inline unsigned char shouldProduce() {
unsigned char terminate = 0;
/* GET LOCK */
terminate = terminate_producer;
/* RELEASE LOCK */
return !terminate;
}
void *Producer(void *threadarg){
while (shouldProduce()){ /* do something */ }
printf("Producer: finalizing thread\n");
return NULL; // <-- use return instead of pthread_exit
}
and in main you would call stopProducers(); instead of rewriting the flag;
It could be due to the compiler heuristically concluding (as an optimization) that terminate_consumer is a variable which is only read in the consumer thread, so it "caches" it in a register and never reads it.
Can you change the declarations of terminate_producer and terminate_consumer to:
volatile int terminate_producer;
volatile int terminate_consumer;
.. and try again?
I have 4 threads to create thread1, thread2, thread3 and thread4:
pthread_create(thread1,NULL,thread_func1,NULL);
pthread_create(thread2,NULL,thread_func2,NULL);
pthread_create(thread3,NULL,thread_func3,NULL);
pthread_create(thread4,NULL,thread_func4,NULL);
looking in the debug , The order of launched threads is not the same as defined in the source code.
Are there a solution to launch the threads with an order that I could define?
The launch order is sequential, in that the create calls happen in the order they're written.
However the scheduler for whatever reason isn't scheduling the newly launched threads in the order you hoped. If the order matters perhaps threads isn't what you want? The big advantage with threads is that they don't always get scheduled in a sequential order!
If you really want though you can use synchronisation primitives (e.g. a series of mutexes, or a condvar) to ensure that up to a certain point happens in predictable order, but from that point onwards the order will still be down to the whims of the scheduler. As an example this code guarantees that each thread will print its ID in the order they were created:
#include <pthread.h>
#include <stdio.h>
static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void sync_threads(const int num, int *cur) {
pthread_mutex_lock(&mut);
while (*cur != num) {
pthread_cond_wait(&cond, &mut);
}
// Do work that must happen in order here:
printf("Thread: %d\n", num);
++*cur;
pthread_mutex_unlock(&mut);
pthread_cond_broadcast(&cond);
}
static int num = 1;
void *thread1(void *d) {
sync_threads(1,&num);
while (1); // Rest of work happens whenever
return NULL;
}
void *thread2(void *d) {
sync_threads(2,&num);
while (1);
return NULL;
}
void *thread3(void *d) {
sync_threads(3,&num);
while (1);
return NULL;
}
void *thread4(void *d) {
sync_threads(4,&num);
while (1);
return NULL;
}
int main() {
pthread_t t1,t2,t3,t4;
pthread_create(&t1, NULL, thread1, NULL);
pthread_create(&t2, NULL, thread2, NULL);
pthread_create(&t3, NULL, thread3, NULL);
pthread_create(&t4, NULL, thread4, NULL);
while(1) {
// some work
}
}
I've used while(1); to simulate some real work happening. It does this with a mutex protecting the "current" thread, i.e. the order of initialisation and then a condvar to make sleeping/waking possible. It broadcasts to all threads who then check to see which one is up next. You could design as system that skips the broadcast, but that complicates things for relatively little gain.
You can also add more synchronisation if required at other points, but the more you synchronise things the less point there is in having threads in the first place.
Ideally if things need to happen in a predictable order they should be done before spawning threads, not as soon as the threads spawn, e.g.:
fixed_init_for_thread1();
fixed_init_for_thread2();
fixed_init_for_thread3();
fixed_init_for_thread4();
pthread_create(thread1,NULL,thread_func1,NULL);
pthread_create(thread2,NULL,thread_func2,NULL);
pthread_create(thread3,NULL,thread_func3,NULL);
pthread_create(thread4,NULL,thread_func4,NULL);
such that by the time the threads are created you don't care which one actually gets given the chance to run first.
I don't think you really care which thread executed first. If you just need an unique identifier for the four threads, check pthread_self. To have sequential IDs, call the ID allocator from within the thread; or generate the ID and pass it as user parameter when calling pthread_create.
here after the solution I used
#include <pthread.h>
#include <stdio.h>
static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static bool wait = TRUE;
void thread_sync() {
pthread_mutex_lock(&mut);
wait = FALSE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mut);
}
void thread_wait_sync() {
pthread_mutex_lock(&mut);
if (wait==TRUE)
{
pthread_cond_wait(&cond,&mut);
}
wait = TRUE;
pthread_mutex_unlock(&mut);
}
void *thread1(void *d) {
thread_sync();
while (1); // Rest of work happens whenever
return NULL;
}
void *thread2(void *d) {
thread_sync();
while (1);
return NULL;
}
void *thread3(void *d) {
thread_sync();
while (1);
return NULL;
}
void *thread4(void *d) {
while (1);
return NULL;
}
int main() {
pthread_t t1,t2,t3,t4;
pthread_create(&t1, NULL, thread1, NULL);
thread_wait_sync();
pthread_create(&t2, NULL, thread2, NULL);
thread_wait_sync();
pthread_create(&t3, NULL, thread3, NULL);
thread_wait_sync();
pthread_create(&t4, NULL, thread4, NULL);
while(1) {
// some work
}
}
Move 'pthread_create(thread2,NULL,thread_func2,NULL);' into thread_func1()
Move 'pthread_create(thread3,NULL,thread_func2,NULL);' into thread_func2()
Move 'pthread_create(thread4,NULL,thread_func2,NULL);' into thread_func3()
This is VERY close to the other question posted recently and just as err.. 'strange'