I'm trying to write a multi-threaded program, the number of threads based on command-line input, and so I can't hard-code pre-declared threads. Is this a valid way of doing it?
int threads = 5; // (dynamic, not hard-coded)
int i = 0;
pthread_t * thread = malloc(sizeof(pthread_t)*threads);
for (i = 0; i < threads; i++) {
pthread_t foobar;
thread[i] = foobar; // will this cause a conflict?
}
for (i = 0; i < threads; i++) {
int ret = pthread_create(&thread[i], NULL, (void *)&foobar_function, NULL);
if(ret != 0) {
printf ("Create pthread error!\n");
exit (1);
}
}
Here's my result from modifications suggested below. Seems to work just fine.
int threads = 5;
int i;
pthread_t * thread = malloc(sizeof(pthread_t)*threads);
for (i = 0; i < threads; i++) {
int ret = pthread_create(&thread[i], NULL, &foobar_function, NULL);
if(ret != 0) {
printf ("Create pthread error!\n");
exit (1);
}
// pthread_join(thread[i], NULL); // don't actually want this here :)
}
sleep(1); // main() will probably finish before your threads do,
free(thread); // so we'll sleep for illustrative purposes
What's in the first cycle? Does it set the array elements to uninitialized value?
So i think that's what you need:
int threads = 5, i = 0, ret = -1;
pthread_t * thread = malloc(sizeof(pthread_t)*threads);
for (i = 0; i < threads; i++) {
ret = pthread_create(&thread[i], NULL, &foobar_function, NULL);
if(ret != 0) {
printf ("Create pthread error!\n");
exit (1);
}
}
It spawns threads threads, starting foobar_function in each. And you have (if everything goes well:)) their ids in thread array. So for example you can cancel second thread by calling pthread_cancel(thread[1]) etc.
The first for loop is not valid C, and I'm not sure what you want it to do. Just remove it and the rest of the code looks ok, aside from the incorrect cast on foobar_function. The cast should be:
(void *(*)(void *))foobar_function
but unless the type is already this, or something very close, your program probably has undefined behavior. It would be better to fix the function signature so no cast is needed.
If you're trying to write a multithreaded program, but don't understand how to allocate a dynamically sized data structure, you may be doing things wrong.
Learn to walk before you run.
Consider using an easier language, and avoiding the use of (explicit) threads.
Threads are very difficult to use correctly; dynamically sized arrays are very easy to achieve (even fairly easy in C)
Related
I'm learning how to use global variables through multithreading, but I have a problem now: about pthread_mutex_lock() and pthread_mutex_unlock().
Correct is usage in function1 or function2? If neither, how to use it correctly?
I just modified one of the elements in the array at that time. For example, after thread1 changed AllSensorInfoArray[2][66].sensorType, the thread1 will change AllSensorInfoArray[2][67].sensorType,now thread2 can change AllSensorInfoArray[2][66].sensorType. In other words, multiple threads are not allowed to modify AllSensorInfoArray[2][66].sensorType at the same time.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
pthread_mutex_t AllSensorMutex;
void *function1(void *arg)
{
int t = 0, i = 0;
/*
some codes
*/
pthread_mutex_lock(&AllSensorMutex);
for (t = 0; t < 100; t++)
{
AllSensorInfoArray[i][t].sensorType = allData[2+t];
}
pthread_mutex_unlock(&AllSensorMutex);
/*
some codes
*/
}
void *function2(void *arg)
{
/*
some codes
*/
int t = 0, i = 0;
for (t = 0; t < 100; t++)
{
pthread_mutex_lock(&AllSensorMutex);
AllSensorInfoArray[i][t].sensorType = allData[2+t];
pthread_mutex_unlock(&AllSensorMutex);
}
/*
some codes
*/
}
int main(void)
{
while(pthread_mutex_init(&AllSensorMutex, NULL))
{
printf("(%s) write mutex init error!\n", __FUNCTION__);
sleep(1);
}
pthread_t thread1;
pthread_t thread2;
int ret = pthread_create(&thread1, NULL, function1, NULL);
if (ret != 0)
{
printf("(%s) failed to create a pthread, return error code : %d.\n", __FUNCTION__, ret);
exit(-1);
}
ret = pthread_create(&thread2, NULL, function2, NULL);
if (ret != 0)
{
printf("(%s) failed to create a pthread, return error code : %d.\n", __FUNCTION__, ret);
exit(-1);
}
while (1)
{
sleep(1);
}
}
Correct is usage in function1 or function2?
Both are equally correct, and will work. The first one is "better" for this particular case.
The first one, which takes the mutex for the duration of the loop is more efficient, because there is less overhead (of locking and unlocking the mutex).
It is best suited for things like copying data.
The second one, which takes the mutex for the duration of accessing each element, is better suited when the modification is more complicated and may take some time (relatively speaking), and you only need to access that one element. However, then you should only take the mutex for the modification itself, and not for the entire computation (or, say, sensor reading):
for (i = 0; i < sensor_count; i++) {
value = read_sensor(i);
pthread_mutex_lock(&mutex);
sensor_reading[i] = value;
pthread_mutex_unlock(&mutex);
}
instead of pthread_mutex_lock(&mutex); sensor_reading[i] = read_sensor(i); pthread_mutex_unlock(&mutex);, because this latter would just hold the mutex while reading the sensor, blocking other threads' access to the array for the duration of the read_sensor(i) call for no sensible reason.
Simple assignment or arithmetic on the array element is not 'slow', and therefore the first function is the recommended pattern here.
In general, the pattern
for (i = 0; i < N; i++) {
pthread_mutex_lock(&mutex);
/* Do something */
pthread_mutex_unlock(&mutex);
}
only releases the mutex for a short duration, and depending on the pthreads implementation, it may not be long enough for any other thread to grab the mutex, even if they were already blocking/waiting on the mutex (in a pthread_mutex_lock(&mutex) call). It is not wrong or an error, though, it just works the same as
pthread_mutex_lock(&mutex);
for (i = 0; i < N; i++) {
/* Do something */
}
pthread_mutex_unlock(&mutex);
and is less efficient than this latter form, because the former does (N-1) extra pthread_mutex_lock() and pthread_mutex_unlock() calls, with no guarantees of any benefits of doing so.
I'm brand new to pthreads, and I'm trying to understand what can be done to avoid problems when using simultaneous threads to write to the same global variables. Here's the simplest possible example:
pthread_t tid1, tid2 ;
int sum = 0 ;
void process()
{
for (int i ; i<100; i++)
sum += 1 ;
}
int main()
{
pthread_create(&tid1, NULL, (void *) process, NULL ) ;
pthread_create(&tid2, NULL, (void *) process, NULL ) ;
pthread_join(tid1, NULL) ;
pthread_join(tid2, NULL) ;
printf("Sum = %d\n", sum) ;
}
When I execute this code, it sometimes prints 200 and sometimes prints 100, implying in the latter case, I assume, that both threads were trying to write to 'sum' at exactly the same time, and one thread got blocked.
In my real world application, 'sum' might be a large array, and one thread might be trying to update one element while another is usually trying to update a different element of the same array.
What is the simplest/cleanest way to ensure that all intended read/write operations on a global variable or array succeed or at least to verify whether the operation succceeded? It isn't necessary to preserve the order of operation.
I seem to have found an answer -- I had not previously known about mutex until it was mentioned in response to a different question:
pthread_t tid1, tid2 ;
pthread_mutex_t lock;
int sum = 0 ;
void process()
{
for (int i ; i<100; i++) {
pthread_mutex_lock(&lock);
sum += 1 ;
pthread_mutex_unlock(&lock);
}
}
int main()
{
if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("\n mutex init failed\n");
return 1;
}
pthread_create(&tid1, NULL, (void *) process, NULL ) ;
pthread_create(&tid2, NULL, (void *) process, NULL ) ;
pthread_join(tid1, NULL) ;
pthread_join(tid2, NULL) ;
pthread_mutex_destroy(&lock);
printf("Sum = %d\n", sum) ;
}
New to C, I was reading here about how to properly pass an argument to a thread. What about if this argument needed to be passed to multiple threads? Where/how should I use free()? Say:
void *foo(void *i) {
int a = *((int *) i);
while(1){
printf("foo running \n");
sleep(1);
}
}
void *bar(void *i) {
int a = *((int *) i);
while(1){
printf("bar running \n");
sleep(1);
}
}
int main() {
pthread_t threads[2];
int i;
for (i = 0; i < 2; i++ ) {
int *arg = malloc(sizeof(*arg));
if ( arg == NULL ) {
fprintf(stderr, "Couldn't allocate memory for thread arg.\n");
exit(1);
}
*arg = i;
pthread_create(&threads[0], NULL, foo, arg);
pthread_create(&threads[1], NULL, bar, arg);
}
for (i = 0; i < 2; i++){
pthread_join(threads[i],NULL);
}
return 0;
}
Is calling free(arg); in main after spawning the threads the same thing / safe?
If all threads needs the exact same argument, and they are not modifying the argument, there's no need to allocate it dynamically at all, instead just declare it as a variable at function scope in the main function. If there's no dynamic allocation, there's no need to free it.
On the other hand if you need separate arguments in a loop like you do, you need to keep track of all arguments, for example using an array:
// Rest of program...
#define NUMBER_OF_ITERATIONS 2
int main(void)
{
int args[NUMBER_OF_ITERATIONS];
pthread_t threads[NUMBER_OF_ITERATIONS][2];
// Create threads
for (unsigned i = 0; i < NUMBER_OF_ITERATIONS; ++i)
{
args[i] = i;
pthread_create(&threads[i][0], NULL, foo, &args[i]);
pthread_create(&threads[i][1], NULL, bar, &args[i]);
}
// Wait for threads to finish
for (unsigned i = 0; i < NUMBER_OF_ITERATIONS; ++i)
{
pthread_join(threads[i][0]);
pthread_join(threads[i][1]);
}
return 0;
}
The program above also solves another problem you have, when you create a total of four threads but only join two.
You need to make sure both threads have finished before calling free(arg).
That means you can do it after you call pthread_join on both threads.
for (i = 0; i < 2; i++){
pthread_join(threads[i],NULL);
}
free(args);
I intend to fire 2 threads in the main thread, and the main thread should wait till all the 2 child threads finish, this is how I do it.
void *routine(void *arg)
{
sleep(3);
}
int main()
{
for (int i = 0; i < 2; i++) {
pthread_t tid;
pthread_create(&tid, NULL, routine, NULL);
pthread_join(&tid, NULL); //This function will block main thread, right?
}
}
In the above code, pthread_join indeed makes main thread wait for the child threads, but the problem is, the second thread won't be created untill the first one finishes. This is not what I want.
What I want is, the 2 threads get created immediatly in the main thread, and then main thread waits for them to finish. Seems like pthread_join cannot do the trick, can it?
I thought, maybe via a semaphore I can do the job, but any other way?
int main()
{
pthread_t tid[2];
for (int i = 0; i < 2; i++) {
pthread_create(&tid[i], NULL, routine, NULL);
}
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
First create all the threads, then join all of them:
pthread_t tid[2];
/// create all threads
for (int i = 0; i < 2; i++) {
pthread_create(&tid[i], NULL, routine, NULL);
}
/// wait all threads by joining them
for (int i = 0; i < 2; i++) {
pthread_join(tid[i], NULL);
}
Alternatively, have some pthread_attr_t variable, use pthread_attr_init(3) then pthread_attr_setdetachedstate(3)
on it, then pass its address to pthread_create(3) second argument. Thos would create the threads in detached state. Or use pthread_detach as explained in Jxh's answer.
Remember to read some good Pthread tutorial. You may want to use mutexes and condition variables.
You could use frameworks wrapping them, e.g. Qt or POCO (in C++), or read a good C++ book and use C++ threads.
Conceptually, threads have each their call stack and are related to continuations. They are "heavy".
Consider some agent-oriented programming approach: as a rule of thumb, you don't want to have a lot of threads (e.g. 20 threads on a 10 core processor is reasonable, 200 threads won't be unless a lot of them are sleeping or waiting) and and do want threads to synchronize using mutex and condition variables and communicate and/or synchronize with other threads quite often (several times per second). See also poll(2), fifo(7), unix(7), sem_overview(7) with shm_overview(7) as another way of communicating between threads. In general, avoid using signal(7) with threads (read signal-safety(7)...), and use dlopen(3) with caution (probably only in the main thread).
A pragmatical approach would be to have most of your threads running some event loop (using poll(2), pselect(2), perhaps eventfd(2), signalfd(2), ....), perhaps communicating using pipe(7) or unix(7) sockets. See also socket(7).
Don't forget to document (on paper) the communication protocols between threads. For a theoretical approach, read books about π-calculus and be aware of Rice's theorem : debugging concurrent programs is difficult.
You could start the threads detached, and not worry about joining.
for (int i = 0; i < 2; i++) {
pthread_t tid;
pthread_create(&tid, NULL, routine, NULL);
pthread_detach(tid);
}
pthread_exit(0);
Or, alternatively, you can have the thread that dies report back to the main thread who it is, so that the threads are joined in the order they exited, rather than in the order you created them in.
void *routine(void *arg)
{
int *fds = (int *)arg;
pthread_t t = pthread_self();
usleep((rand()/(1.0 + RAND_MAX)) * 1000000);
write(fds[1], &t, sizeof(t));
}
int main()
{
int fds[2];
srand(time(0));
pipe(fds);
for (int i = 0; i < 2; i++) {
pthread_t tid;
pthread_create(&tid, NULL, routine, fds);
printf("created: %llu\n", (unsigned long long)tid);
}
for (int i = 0; i < 2; i++) {
pthread_t tid;
read(fds[0], &tid, sizeof(tid));
printf("joining: %llu\n", (unsigned long long)tid);
pthread_join(tid, 0);
}
pthread_exit(0);
}
#include<stdio.h>
#include<pthread.h>
int icnt = 0; //in non_bss data segment
pthread_mutex_t lock; //lock variable created stored into bss data segment
void *Thread_count(void* args) //syncronization
{
pthread_mutex_lock(&lock); //lock aquire
icnt++;
for(int x = 1; x <= icnt; x++)
{
printf("Hello from Thread_count : %d \n",icnt);
}
printf("\n");
pthread_mutex_unlock(&lock); //release lock
pthread_exit(NULL); //exit from child thread
}
int main()
{
pthread_t threads[4]; //created array of {unsigned long int}
int status = 0;
//creating threads in loop
for(int i = 1; i <= sizeof(threads)/sizeof(threads[0]); i++)
{
pthread_create(&threads[i], NULL, &Thread_count, NULL);
}
//waiting for threads in loop
for(int j = 1; j <= sizeof(threads)/sizeof(threads[0]); j++)
{
pthread_join(threads[j], &status);
printf("Thread number : %d <--> Thread status : %d\n",j, status);
}
pthread_exit(0); //end of main thread
}
In my main function, I spawn j threads which all compute the same task in parallel -- and then I want to wait for them to finish before exiting.
int main(...) {
// ...
int threads = 6;
pthread_t* thread = malloc(sizeof(pthread_t)*threads);
for(i = 0; i < threads; i++) {
struct thread_param *tp;
tp = malloc(sizeof(*tp));
// ...
int ret = pthread_create(&thread[i], NULL, &control, (void*)tp);
if(ret != 0) {
printf ("Create pthread error!\n");
exit (1);
}
}
for (j = 0; j < threads; j++) {
printf("JOINING THREAD: %i\n", j);
pthread_join( &thread[j], NULL);
}
exit(0);
}
However, nothing waits. Main just exits without ever completing the threaded tasks. Am I missing something?
hey, try pthread_join( thread[j], NULL); i think the problem is with types. I checked docs:
int pthread_join(pthread_t thread, void **value_ptr);
and thread is p_thread*, and thread[j] is p_thread, while &thread[j] is p_thread*, which is invalid. There just might internal error happen.
Edit: Yeah, I am very positive with that, pthread_t is basically int, so pthread_t* is accepted, it is just invalid thread handle, so pthread_join fails internally.