I'm doing parallel sorting using pthreads. Currently, I'm working with 4 threads and I have just started out , so right now no threads access same global locations. ( I have declared two variables globally, variables are arrays of large size and I'm making sure no two threads access the same index.)
Inside AASort , I have another function being called. This code works if I don't call any function within the AASort function.
unsigned int Numbers [N/4] [4];
unsigned int vMergedArray[NumProcs][64][4];
unsigned int v[NumProcs][2][4];
main()
{
/* Initialize array of thread structures */
threads = (pthread_t *) malloc(sizeof(pthread_t) * NumProcs);
assert(threads != NULL);
for(threadId=0; threadId < NumProcs; threadId++) {
ret = pthread_create(&threads[threadId], &attr, AASort, (void*) threadId);
assert(ret == 0);
}
for(threadId=0; threadId < NumProcs; threadId++) {
ret = pthread_join(threads[threadId], NULL);
assert(ret == 0);
}
}
Related
I'm trying to build a basic "game" server in C, I stock each file descriptor of an accepted socket in an int *, each of these are stocked in int ** clients. I then create a thread and pass clients as its argument.
Here's the code:
game_server_threaded.c
#define PLAYERS 4
int ** clients;
/* Setting up server... */
clients = malloc(sizeof(int *) * PLAYERS);
while (1)
{
for (int i = 0; i < PLAYERS; i++) {
clients[i] = malloc(sizeof(int));
*clients[i] = accept(server_sock,
(struct sockaddr *)&client_address, &size);
printf("s%d: %d\n", i, *clients[i]);
}
pthread_t th;
if (pthread_create(&th, NULL, play_game, clients) < 0)
die("create thread");
}
void * play_game(void * s)
void * play_game(void * s)
{
int ** clients = (int **) s;
srand (time(NULL));
int k = rand() % MAX_K;
int tries = 3;
int turn = 0;
for (int i = 0; i < PLAYERS; i++)
{
printf("s%d: %d\n", i, *clients[i]);
}
/* Game mechanics... */
}
However, the output is very weird. In the thread, all *clients[i] are set, except for *clients[0].
Here it is:
s0: 4
s1: 5
s2: 6
s3: 7
s0: 0
s1: 5
s2: 6
s3: 7
I've tested this extensively with different casts and such. I've also created a version which sends this struct to the thread:
struct player_threads {
char * msg;
char c;
int ** clients;
};
In the thread, msg and c are intact but the first element of clients is still 0!
I managed to get it working with a simple int * clients, but still, I can't comprehend this behaviour, could someone explain it to me?
Thank you.
EDIT****
The file from which the above code comes from is relatively short, it can be found here if you want to reproduce it.
https://pastebin.com/61nRKvQf
The created threads are sharing data that they expected to remain stable but is actually being modified outside the thread.
Specifically, the memory pointed to by clients, pointing to an "array" of int * is allocated before any threads are created. It is being filled in with a new set of int * before each new thread is created and is then passed to the new thread in the final argument of the pthread_create call. When the new thread examines the "array" of int *, it may see a mixture of the original elements at the time of the pthread_create call plus some elements that have since been overwritten by the main thread. Also, because assignment to an object of pointer type is not guaranteed to be atomic, it is also possible for the thread to access a partially updated (and therefore invalid) pointer value.
In the example given, the first four lines are printed by the main thread by this code:
for (int i = 0; i < PLAYERS; i++) {
clients[i] = malloc(sizeof(int));
*clients[i] = accept(server_sock,
(struct sockaddr *)&client_address, &size);
printf("s%d: %d\n", i, *clients[i]);
}
Output:
s0: 4
s1: 5
s2: 6
s3: 7
The main thread then creates a new thread:
pthread_t th;
if (pthread_create(&th, NULL, play_game, clients) < 0)
die("create thread");
The main thread then repeats the above for loop. The first thing that does is overwrite clients[0] with a new pointer value from malloc(sizeof(int)) and then it blocks on the accept call.
Meanwhile, the thread starts and prints stuff from the clients array, but clients[0] may have already been overwritten.
Output:
(At this point, the main thread has overwritten client[0]. The contents of client[0][0] are indeterminate at this point, but happens to contain 0 here.) ...
s0: 0
(At this point, the main thread is blocked on the call to accept, so clients[1] through to clients[3] still have the same values they had at the time of the call to pcreate_thread.) ...
s1: 5
s2: 6
s3: 7
To correct the problem, a new clients block needs to be allocated for each thread. That can be done by moving the allocation of clients into the loop that creates the new threads:
#define PLAYERS 4
int ** clients;
/* Setting up server... */
while (1)
{
clients = malloc(sizeof(int *) * PLAYERS);
for (int i = 0; i < PLAYERS; i++) {
clients[i] = malloc(sizeof(int));
*clients[i] = accept(server_sock,
(struct sockaddr *)&client_address, &size);
printf("s%d: %d\n", i, *clients[i]);
}
pthread_t th;
if (pthread_create(&th, NULL, play_game, clients) < 0)
die("create thread");
}
As an aside, there is unnecessary indirection in the use of int **clients since all that is really being passed in this example is one int value per player (containing the file descriptor of the accepted socket connection for that player). That could be simplified as follows:
Main thread
#define PLAYERS 4
int * clients;
/* Setting up server... */
while (1)
{
clients = malloc(sizeof(int) * PLAYERS);
for (int i = 0; i < PLAYERS; i++) {
clients[i] = accept(server_sock,
(struct sockaddr *)&client_address, &size);
printf("s%d: %d\n", i, clients[i]);
}
pthread_t th;
if (pthread_create(&th, NULL, play_game, clients) < 0)
die("create thread");
}
Game thread
void * play_game(void * s)
{
int * clients = s;
srand (time(NULL));
int k = rand() % MAX_K;
int tries = 3;
int turn = 0;
for (int i = 0; i < PLAYERS; i++)
{
printf("s%d: %d\n", i, clients[i]);
}
/* Game mechanics... */
}
For the version that passes a pointer to a struct player_threads to each thread, with the clients member type simplified to int *:
struct player_threads
struct player_threads {
char * msg;
char c;
int * clients;
};
Main thread
#define PLAYERS 4
struct player_threads * players;
/* Setting up server... */
while (1)
{
players = malloc(sizeof(*players));
players->clients = malloc(sizeof(int) * PLAYERS);
players->msg = "Hello";
players->c = 'X';
for (int i = 0; i < PLAYERS; i++) {
players->clients[i] = accept(server_sock,
(struct sockaddr *)&client_address, &size);
printf("s%d: %d\n", i, players->clients[i]);
}
pthread_t th;
if (pthread_create(&th, NULL, play_game, players) < 0)
die("create thread");
}
Game thread
void * play_game(void * s)
{
struct player_threads * players = s;
srand (time(NULL));
int k = rand() % MAX_K;
int tries = 3;
int turn = 0;
for (int i = 0; i < PLAYERS; i++)
{
printf("s%d: %d\n", i, players->clients[i]);
}
/* Game mechanics... */
}
As another aside, it would be better to replace the calls to srand and rand with a call to rand_r because the rand call might not be thread-safe:
unsigned int seed = time(NULL);
int k = rand_r(&seed) % MAX_K;
seed needs to be in storage local to the thread. In the above, it is on the thread's stack, but it may be better to provide storage for it as a member of struct player_threads:
struct player_threads {
char * msg;
char c;
unsigned int seed;
int * clients;
};
players->seed = time(NULL);
int k = rand_r(&players->seed) % MAX_K;
I am just a beginner in Programming using C.For my college project I want to create a multi-threaded server application to which multiple clients can connect and transfer there data which can be saved in a database.
After going through many tutorials I got confused about how to create multiple threads using pthread_create.
Somewhere it was done like:
pthread_t thr;
pthread_create( &thr, NULL , connection_handler , (void*)&conn_desc);
and somewhere it was like
pthread_t thr[10];
pthread_create( thr[i++], NULL , connection_handler , (void*)&conn_desc);
I tried by implementing both in my application and seems to be working fine. Which approach of the above two is correct which I should follow.
sorry for bad english and description.
Both are equivalent. There's no "right" or "wrong" approach here.
Typically, you would see the latter when creating multiple threads, so an array of thread identifiers (pthread_t) are used.
In your code snippets, both create just a single thread. So if you want to create only one thread, you don't need an array. But this is just like declaring any variable(s) that you didn't use. It's harmless.
In fact, if you don't need the thread ID for any purpose, (for joining or changing attributes etc.), you can create multiple threads using a single thread_t variable without using an array.
The following
pthread_t thr;
size_t i;
for(i=0;i<10;i++) {
pthread_create( &thr, NULL , connection_handler , &conn_desc);
}
would work just fine. Note that the cast to void* is unnecessary (last argument to pthread_create()). Any data pointer can be implicitly converted to void *.
Sample Example of multiple thread :
#include<iostream>
#include<cstdlib>
#include<pthread.h>
using namespace std;
#define NUM_THREADS 5
struct thread_data
{
int thread_id;
char *message;
};
void *PrintHello(void *threadarg)
{
struct thread_data *my_data;
my_data = (struct thread_data *) threadarg;
cout << "Thread ID : " << my_data->thread_id ;
cout << " Message : " << my_data->message << endl;
pthread_exit(NULL);
}
int main ()
{
pthread_t threads[NUM_THREADS];
struct thread_data td[NUM_THREADS];
int rc, i;
for( i=0; i < NUM_THREADS; i++ )
{
cout <<"main() : creating thread, " << i << endl;
td[i].thread_id = i;
td[i].message = "This is message";
rc = pthread_create(&threads[i], NULL,
PrintHello, (void *)&td[i]);
if (rc){
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);
}
The first one you provided creates a single thread.
The second one (if looped) has the potential to spawn 10 threads.
Basically the pthread_t type is a handler for the thread so if you have an array of 10 of them then you can have 10 threads.
For everyone, use a thread list because it will not be free if you call once pthread_join().
Code exemple :
int run_threads(void)
{
int listLength = 5;
pthread_t thread[listLength];
//Create your threads(allocation).
for (int i = 0; i != listLength; i++) {
if (pthread_create(&thread[i], NULL, &routine_function, NULL) != 0) {
printf("ERROR : pthread create failed.\n");
return (0);
}
}
//Call pthread_join() for all threads (they will get free) and all threads
//will terminate at this position.
for (int i = 0; i != listLength; i++) {
if (pthread_join(thread[i], NULL) != 0) {
printf("ERROR : pthread join failed.\n");
return (0);
}
}
//return 1 when all threads are terminated.
return (1);
}
First of all, this has to do with homework. Just a little hint would be enough.
What I have to do is to detect when a variable(signal) has changed and announce it in 1 microsecond or less. My progress so far:
int main(int argc, char **argv)
{
int i;
N = atoi(argv[1]);
if (argc != 2) {
printf("Usage: %s N\n"
" where\n"
" N : number of signals to monitor\n"
, argv[0]);
return (1);
}
// set a timed signal to terminate the program
signal(SIGALRM, exitfunc);
alarm(20); // after 20 sec
// Allocate signal, time-stamp arrays and thread handles
signalArray = (int *) malloc(N*sizeof(int));
timeStamp = (struct timeval *) malloc(N*sizeof(struct timeval));
pthread_t sigGen;
pthread_t *sigDet = (pthread_t*) malloc(N * sizeof(pthread_t));
long *signalid = (long*) malloc(N * sizeof(long));
for (i=0; i<N; i++) {
signalArray[i] = 0;
}
for (i = 0; i < N; i++)
{
signalid[i] = (long) i;
pthread_create (&sigDet[i], NULL, ChangeDetector, (void*) signalid[i]);
}
pthread_create (&sigGen, NULL, SensorSignalReader, NULL);
// wait here until the signal
for (i = 0; i < N; i++)
{
pthread_join (sigDet[i], NULL);
}
return 0;
}
void *SensorSignalReader (void *arg)
{
char buffer[30];
struct timeval tv;
time_t curtime;
srand(time(NULL));
while (1) {
int t = rand() % 10 + 1; // wait up to 1 sec in 10ths
usleep(t*100000);
int r = rand() % N;
signalArray[r] ^= 1;
if (signalArray[r]) {
gettimeofday(&tv, NULL);
timeStamp[r] = tv;
curtime = tv.tv_sec;
strftime(buffer,30,"%d-%m-%Y %T.",localtime(&curtime));
printf("Changed %5d at Time %s%ld\n",r,buffer,tv.tv_usec);
}
}
}
void *ChangeDetector (void *arg)
{
char buffer[30];
struct timeval tv;
time_t curtime;
long n = (long) arg;
while (1) {
while (signalArray[n] == 0) {}
pthread_mutex_lock(&mutex);
gettimeofday(&tv, NULL);
curtime = tv.tv_sec;
strftime(buffer,30,"%d-%m-%Y %T.",localtime(&curtime));
printf("Detcted %5ld at Time %s%ld after %ld.%06ld sec\n", n, buffer,tv.tv_usec,
tv.tv_sec - timeStamp[n].tv_sec,
tv.tv_usec - timeStamp[n].tv_usec);
pthread_mutex_unlock(&mutex);
while (signalArray[n] == 1) {}
}
}
With this implementation my program achieves to detect up to 3 signals in time <= 1 us. When more than 3 the response delay up to few ms. How could I detect even more signals in that time? I was wondering how thread tasks are allocated in CPU cores? I've read that it's too painful to manage what is executed on each core by code? Would I earn something with that effort?
Your ChangeDetector() relies on busy-waiting on the flag. The problem is that you can't have more processes simultaneously busy-waiting than you have CPUs - only some subset of your ChangeDetector() processes are actually going to be running at any point in time.
This means that quite often, you have to wait for the right ChangeDetector thread to be scheduled back onto the CPU before it can run and notice that the flag has changed.
If you want to have one ChangeDetector thread for every flag, then you will need to use a non-busy-waiting method, like pthread condition variables (you can have one mutex / condition variable pair per flag). I am not sure if you will be able to get sub-microsecond latency this way, though.
If you want really want to stick with the busy-waiting method, you'll need to limit your number of ChangeDetector threads to less than the number of CPUs, by having each thread responsible for checking multiple array locations in every loop.
I learn threads. I have read that thread terminates after it is out of a function (that is passed as parameter to pthread_create function).
So I create threads in the loop, they are executed and afterwards they are terminated.
(sorry for some long code)
But when I call a function pthread_create, new threads get the same ids. Why?
struct data {
FILE *f;
};
void *read_line_of_file(void *gdata) {
pthread_mutex_lock(&g_count_mutex); // only one thread can work with file,
//doing so we block other threads from accessing it
data *ldata = (data *) gdata;
char line[80];
int ret_val =fscanf(ldata->f,"%s",line);
pthread_mutex_unlock(&g_count_mutex); // allow other threads to access it
if (ret_val != EOF)
printf("%s %lu\n ", line, pthread_self());
// some time consuming operations, while they are being executed by one thread,
// other threads are not influenced by it (if there are executed on different cores)
volatile int a=8;
for (int i=0;i <10000;i++ )
for (int i=0;i <10000;i++ ) {
a=a/7+i;
}
if (ret_val == EOF) // here thread ends
pthread_exit((void *)1);
pthread_exit((void *)0);
}
int main() {
int kNumber_of_threads=3, val=0;
pthread_t threads[kNumber_of_threads];
int ret_val_from_thread=0;
data mydata;
mydata.f = fopen("data.txt","r");
if ( mydata.f == NULL) {
printf("file is not found\n");
return 0;
}
for( ; val != 1 ;) {
// THIS IS THAT PLACE, IDs are the same (according to the number of processes),
// I expected them to be changing..
for(int i=0; i<kNumber_of_threads; i++) {
pthread_create(&threads[i],NULL,read_line_of_file, &mydata);
}
for(int i=0; i<kNumber_of_threads; i++) {
pthread_join(threads[i], (void **) &ret_val_from_thread);
if (ret_val_from_thread != 0)
val = ret_val_from_thread;
}
printf(" next %d\n",val);
}
printf("work is finished\n");
fclose(mydata.f);
return 0;
}
as result, I see that id of threads are not being changed:
I wonder, are new threads really created?
Thanks in advance!
Thread IDs are only guaranteed to be different among currently running threads. If you destroy a thread and create a new one, it may well be created with a previously used thread ID.
I'm keep getting a segmentation fault from where I create thread and declare some variables in the struct...
Does anyone know why?
dispatch_queue_t *dispatch_queue_create(queue_type_t queueType){
int cores = num_cores();
printf("message-queuecreate1");
dispatch_queue_t *dispatch_queue = (dispatch_queue_t *) malloc(sizeof(dispatch_queue_t));
dispatch_queue->HEAD = NULL;
dispatch_queue->END = NULL;
//create a thread array for dispatcher and worker threads
dispatch_queue_thread_t *threads[cores+1];
threads[cores+1]= (dispatch_queue_thread_t *)malloc(sizeof(dispatch_queue_thread_t));
//create semaphores
sem_t queue_task_semaphore;
sem_t queue_thread_semaphore;
sem_t queue_wait_semaphore;
sem_init(&queue_task_semaphore, 0, 1);
sem_init(&queue_thread_semaphore,0,1);
sem_init(&queue_wait_semaphore,0,1);
dispatch_queue->queue_task_semaphore = queue_task_semaphore;
dispatch_queue->queue_thread_semaphore = queue_thread_semaphore;
dispatch_queue->queue_wait_semaphore = queue_wait_semaphore;
//create dispatcher thread
//segmentation fault #1////////////////
threads[0]->current_task=NULL;
threads[0]->queue=dispatch_queue;
pthread_create(threads[0]->thread, NULL, dispatcher_threadloop, threads[0]);
//////////////////////////////////////
if (queueType == CONCURRENT){
int i = 0;
int thread_id=0;
//create worker thread array if the type of the queue is concurrent
while(i<cores){
//create worker thread
thread_id = i+1;
//segmentation fault #2//////////
threads[i+1]->queue=dispatch_queue;
threads[thread_id]->thread=NULL;
threads[thread_id]->current_task=NULL;
pthread_create(threads[thread_id]->thread, NULL, worker_threadloop, (void *)(long)i);
////////////////////////////////
printf("thread %d is created\n",i);
i++;
}
} else {//do smth}
//segmentation fault# 3////////////////
threads[1]->thread=worker_thread;
threads[1]->queue=dispatch_queue;
threads[1]->current_task=NULL;
//////////////////////////////////////
}
return dispatch_queue;
}
Your code is riddled with problems:
Accessing threads[core + 1] is invalid. Also, you're not allocating memory for the threads[0] ... threads[core].
dispatch_queue_thread_t *threads[cores+1];
threads[cores+1]= ....;
So these will fail:
threads[0]->current_task=NULL; /* See above. */
threads[i+1]->queue=dispatch_queue; /* Again, no memory allocated. */
There could be other problems but I would start by slashing the cores+1 stuff and replacing it with:
for (i = 0; i < cores; i++) {
threads[i] = malloc(sizeof(*threads[i]));
}
Assuming
threads[]->thread
is a pthread_t (and not a pthread_t *)
You need to give the reference:
pthread_create(&threads[thread_id]->thread, NULL, worker_threadloop, (void *)(long)i);
.