Ordering the execution of two threads - c

I wanna write two threads, first will read a string from the console, and the second will output the number of characters in it.
To do so, I have to set the order of executing the threads, reading first, writing second.
Also I want one thread to execute at the time.
How can I do this?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *printCharacterNumber(void *ptr);
void *readMessage(void *ptr);
int main()
{
pthread_t thread1, thread2;
int iret1, iret2;
iret1 = pthread_create(&thread1, NULL, printMessage, NULL);
iret2 = pthread_create(&thread2, NULL, printCharacterNumber, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;
}
void *readMessage(void *ptr)
{
char *message;
fscan("%s", &message);
}
void *printCharacterNumber(void *ptr)
{
printf("%s", message); // I'll add counting when it will work
}

The biggest interest of genine (pthread) threads is to enable parallel execution (taking profit of the several cores most laptops and desktops have)...
Read some pthread tutorial ...
You may want to use barriers. Read more about pthread_barrier_wait & pthread_barrier_init
If you want to serialize some counter, you could use (with recent C11 compilers, e.g. GCC 4.9) some atomic builtins, or more usually a mutex, see pthread_mutex_init & pthread_mutex_lock etc....:
static pthread_mutex_t mtx = PTHREAD_MUTEX_INIT;
static long counter;
void increment_serialized_counter (void) {
pthread_mutex_lock(&mtx);
counter++;
pthread_mutex_unclock(&mtx);
}
long get_serialized_counter (void) {
long r = 0;
pthread_mutex_lock(&mtx);
r = counter;
pthread_mutex_unclock(&mtx);
return r;
}
You probably should use a mutex for your message variable, if it was static!

Related

while loop reads same variable from 2 different pthreads but code not running

I am trying to detect core to core latency in simple memory sharing. My objective is to read a global variable from two different threads. Let's say the variable is x=0 at the beginning. Now one thread will read the value and change the x to 1. Another thread is reading the same variable and as soon as it reads x=1, it makes it 0. I have written the following code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/time.h>
double getsecs(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + tv.tv_usec / 1.0e6;
}
int x=0;
//count=0;
void* changetoone(void *arg)
{
//sched_setaffinity(0);
for (int i=0; i<10000; i++){
while(x!=1)
{
x=1;
printf("%d", x);
}
}
return 0;
}
void* changetozero(void *arg){
//sched_setaffinity(5);
for (int i=0; i<10000; i++){
while(x!=0)
{
x=0;
printf("%d", x);
}
}
return 0;
}
int main()
{
pthread_t thread1;
pthread_create(&thread1, NULL, changetoone, &x);
pthread_t thread2;
pthread_create(&thread2, NULL, changetozero, &x);
pthread_join(&thread1, NULL);
pthread_join(&thread2, NULL);
}
For some reason, the code is not running. I am not familiar with using pthread and I think I made some silly mistakes. Can anybody point out the mistake for me, please?
The first argument to pthread_join is pthread_t, not pthread_t*. So you shouldn't use & when calling it.
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
The actual behavior of the program is undefined because of lack of synchronization between the threads when accessing x. But this will at least allow the threads to run.

Pthread Mutex Segfault

I've never worked with pthreads before and am simply trying to familiarize myself with them. As such, I've written the following test code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int count = 0;
void *increment(void *tex);
int main(int argc, char **argv) {
pthread_t t1, t2, t3;
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
pthread_create(&t1, NULL, &increment, &mutex);
pthread_create(&t2, NULL, &increment, &mutex);
pthread_create(&t2, NULL, &increment, &mutex);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
printf("Value of count is: %d\n", count);
}
void *increment(void *tex) {
pthread_mutex_t *mutex = (pthread_mutex_t *) mutex;
for (int i = 0; i < 100; i++) {
pthread_mutex_lock(mutex);
count++;
pthread_mutex_unlock(mutex);
}
return NULL;
}
I'm compiling the code with GCC using the proper -pthread flag, yet, for whatever reason, any time that any of the threads reach the mutex locking line, segfault. Upon further investigation with GDB, I've discovered that the mutex pointer appears to be invalid inside of the increment function even though I initialized it in main, passed it in as the argument to pthread_create, and have called join on each thread to ensure that main is still in scope. I'm at a loss for why this is happening, and could use some help. Thanks!
You've got:
pthread_mutex_t *mutex = (pthread_mutex_t *) mutex;
what you need is:
pthread_mutex_t *mutex = (pthread_mutex_t *) tex;

printf with pthreads in C

I am working with pthreads right now doing the producer/consumer problem. I am currently just trying to get the producer working and using printf statements to see where my issues are. The problem is the code compiles just fine but when I run it, it doesn't do anything but seems to run just fine. I have tried setting my first line to a printf statement but even that does not print. I have tried using fflush as well and I am running out of ideas. My question why would even the first printf statement get skipped?
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
void *producer();
pthread_mutex_t lock;
pthread_cond_t done, full, empty;
int buffer[10];
int in = 0, out = 0;
int min = 0, max = 0, numOfItems = 0, total = 0;
double avg;
void *producer() {
srand(time(NULL));
int n = rand();
int i;
for(i = 0; i < n; i++)
{
int random = rand();
pthread_mutex_lock(&lock);
buffer[in++] = random;
if(in == 10)
{
pthread_cond_signal(&full);
printf("Buffer full");
pthread_mutex_unlock(&lock);
sleep(1);
}
}
pthread_exit(NULL);
}
void *consumer() {
pthread_exit(NULL);
}
int main(int argc, char *argv[]){
printf("test");
//Create threads and attribute
pthread_t ptid, ctid;
pthread_attr_t attr;
//Initialize conditions and mutex
pthread_cond_init(&full, NULL);
pthread_cond_init(&empty, NULL);
pthread_cond_init(&done, NULL);
pthread_mutex_init(&lock, NULL);
//Create joinable state
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&ptid, &attr,(void *)producer,NULL);
pthread_create(&ctid, &attr,(void *)consumer,NULL);
pthread_join(ptid,NULL);
pthread_join(ctid,NULL);
printf("Program Finished!");
pthread_exit(NULL);
}
man pthread_mutex_init
pthread_mutex_init initializes the mutex object pointed to by mutex
according to the mutex attributes specified in mutexattr. If mutexattr
is NULL, default attributes are used instead.
The LinuxThreads implementation supports only one mutex attributes, the
mutex kind... The kind of a mutex determines whether it can be locked again by
a thread that already owns it. The default kind is fast...
If the mutex is already locked by the calling thread, the behavior of
pthread_mutex_lock depends on the kind of the mutex. If the mutex is of
the fast kind, the calling thread is suspended until the mutex is
unlocked, thus effectively causing the calling thread to deadlock.
That's what happens to your producer: it deadlocks in the call
pthread_mutex_lock(&lock);
- except in the unlikely case n < 2 - thus producing no output.

multithreading(pthread) compete code

#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
int global;
int i = 30;
int j = 30;
int k = 30;
pthread_mutex_t mutex;
void* child1(void* arg)
{
while(k--)
{
pthread_mutex_lock(&mutex);
global++;
printf("from child1\n");
printf("%d\n",global);
pthread_mutex_unlock(&mutex);
}
}
void* child2(void* arg)
{
while(j--)
{
pthread_mutex_lock(&mutex);
global++;
printf("from child1\n");
printf("%d\n",global);
pthread_mutex_unlock(&mutex);
}
}
int main()
{
pthread_t tid1, tid2;
pthread_mutex_init(&mutex, NULL);
pthread_create(&tid1, NULL, child1, NULL);
pthread_create(&tid2, NULL, child2, NULL);
while(i--)
{
pthread_mutex_lock(&mutex);
global++;
printf("from main\n");
printf("%d\n",global);
pthread_mutex_unlock(&mutex);
}
return 0;
}
I'm new to pthread and multithreading, the result of this code is from main xx and child1 appeared rarely, the three threads never appear together, what's the problem?
Most of time in the critical sections will be spent in the printf calls. You might try:
{
int local;
pthread_mutex_lock(& mutex);
local = ++global;
pthread_mutex_unlock(& mutex);
printf("from <fn>\n%d\n", local);
}
This still doesn't give any guarantee of 'fairness' however, but the printf call is very likely to use a system call or I/O event that will cause the scheduler to kick in.
Your program is similar to the Dining Philosophers Problem in many respects. You don't want any thread to 'starve', but you have contention between threads for the global counter, and you want to enforce an orderly execution.
One suggestion in code replace printf("from child1\n"); to printf("from child2\n"); in void* child2(void* arg) function. And if you want ensure all threads to complete please add the following lines at end of main function.
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
I think you should use 3 differents mutex , by the way use pconditional control in order to avoid having unsafe access

multithread launching order

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'

Resources