threads running simultaniously - c

so I want to have 3 threads that all increment a global integer. I thought that when a thread was created that it was simulair to a fork in that main would continue to execute code at the same time as the newly created thread. That's not what is happenin though, as the second and third threads are never created untill after the first thread is complete.
void * say_it( void * )
{
int count = 0;
while(BUFFER < 24)
{
//LOCK
if (pthread_mutex_lock(&output_lock) != 0)
{
perror("Could not lock output: ");
exit(-1);
}
//print message
cout << "TID: " << pthread_self() << " PID: " << "WORK IN PROGRESS " << "Buffer: " << BUFFER << endl;
BUFFER++;
//UNLOCK
if (pthread_mutex_unlock(&output_lock) != 0)
{
perror("Could not unlock output: ");
exit(-1);
}
count++;
}
//print final message
cout << "TID: " << pthread_self() << " worked on the buffer " << count << " times" << endl;
}
int main(int argc, char *argv[])
{
int num_threads = 3;
pthread_t *thread_ids;
void *p_status;
//Use unbuffered output on stdout
setvbuf(stdout, (char *) NULL, _IONBF, 0);
//Set up an output lock so that threads wait their turn to speak.
if (pthread_mutex_init(&output_lock, NULL)!=0)
{
perror("Could not create mutex for output: ");
return 1;
}
//Create 3 THREADS
thread_ids = new pthread_t[num_threads];
// generate threads
for (int i = 0; i < num_threads; i++)
{
int *arg = new int;
*arg = i;
if( pthread_create(&thread_ids[i],NULL,say_it,NULL) > 0)
{
perror("creating thread:");
return 2;
}
if (pthread_join(thread_ids[i], &p_status) != 0)
{
perror("trouble joining thread: ");
return 3;
}
}
return 0;
}
I have also experimented with placing sleep(1) in areas of the program to no success.
Can anyone explain this to me?
Thanks!

When you call pthread_join, main will block until that thread finishes. You need to create all of the threads, before calling pthread_join on the threads.
Side note: you're calling pthread_create again after the comment that says // join threads and print their return values. That all needs to be removed.

In the loop, you create a thread and then join with it, so you don't create the next thread until the first one has finished. You have no concurrency here.
The second loop of 10 looks plain wrong since you only allocated space for 3 thread ids, yet here you are creating 10 threads.

You are creating thread and waiting for the thread to complete. Move the join code out of for loop as below.
for (int i = 0; i < num_threads; i++)
{
int *arg = new int;
*arg = i;
if( pthread_create(&thread_ids[i],NULL,say_it,NULL) > 0)
{
perror("creating thread:");
return 2;
}
}
for (int i = 0; i < num_threads; i++)
{
if (pthread_join(thread_ids[i], &p_status) != 0)
{
perror("trouble joining thread: ");
return 3;
}
}

Related

Thread in C just halting execution?

I have a robot that I am controlling through a specific library with C.
I need a thread that checks if a button is pressed, and if it is, the program exits.
This check should happen separated from the main thread, so that I can run the robot movement code along with the button check code.
I've made a small PoC but it's not working: the program flow halts and the button check is executed indefinitely.
Here is the code. If some variables/functions are missing in this snippet, don't worry, they are there in the actual code.
void *brick_controller(void *vargp){
printf("Second thread is working!\n");
uint8_t button_buffer;
while(true)
{
size_t result = ev3_read_keys(&button_buffer);
//printf("ass %d\n", buf);
if(button_buffer == 32){
exit(666);
}
}
}
int main(int argc, char** argv)
{
printf( "Waiting the EV3 brick online...\n" );
if ( ev3_init() < 1 ) return ( 1 );
printf( "*** ( EV3 ) Hello! ASS ***\n" );
ev3_sensor_init();
ev3_tacho_init();
app_alive = app_init();
if (app_alive == 0)
{
/*int distance = 250;
if (argc == 1)
{}
else if (argc == 2)
{
default_speed = atoi(argv[1]);
}
else if (argc == 3)
{
default_speed = atoi(argv[1]);
distance = atoi(argv[2]);
}
else {
printf("Too many arguments!\n");
return 0;
}
printf("Speed:%d\n"
"Distance:%d\n", default_speed, distance);
drive(default_speed, distance);
*/
pthread_create(&brick_controller_thread, NULL, *brick_controller, NULL);
pthread_join(brick_controller_thread, NULL);
int i = 0;
while(i < 200){ // This never executes :(
i++;
printf("All is running! %d\n", i);
}
} else {
printf("App initialization failed! Error code: %d\n", app_alive);
return 2;
}
ev3_uninit();
return 0;
According to the man page:
The pthread_join() function waits for the thread specified by thread
to terminate. If that thread has already terminated, then
pthread_join() returns immediately. The thread specified by thread
must be joinable.
pthread_join waits for the thread to terminate, which never will.

C++ distributed program blocking

I'm trying to do a distributed program to do a simple job (checks prime numbers) and apparently the program is falling in a blocking wait and I don't know why.It's a producer-consumer program and have to create one thread for each producers call or consumers call. Could anyone help me?
Ps: The problem is intermittent.
My code is bellow:
#include <pthread.h>
#include <iostream>
#include <atomic>
#include <time.h>
#include <mutex>
#include <semaphore.h>
#include <cmath>
using namespace std;
#define N 2 //buffer size
#define Np 1 //number of producer threads
#define Nc 8 //number of consumer threads
sem_t full, empty; //semaphores declaration
pthread_mutex_t bufferbusy, finish; //mutex declaration
long numbers[N]; //buffer declaration
int finished = 0; //flag declaration
int M = 0; //counter declaration
bool isPrime(long n){
/*checks if long n is prime*/
for (int i = 2; i < sqrt(n) ; i++)
if (n % i == 0)
return false;
return true;
}
void *producer(){
/*waits empty semaphore > 1 then puts a number in the buffer (with exclusive access)*/
while(M<10000){
sem_wait(&empty); //WAIT EMPTY
pthread_mutex_lock(&bufferbusy); //locks bufferbusy mutex to ensure exclusive access
for (int i = 0 ; i < N ; i++){ //scrolls the buffer
if (numbers[i] == 0){ //if finds an empty buffer's position
numbers[i] = rand()%10000001+1; //fit this position with a random number
break; //leave the loop
}
}
pthread_mutex_unlock(&bufferbusy); //unlock bufferbusy mutex
sem_post(&full); //SIGNAL FULL
}
pthread_mutex_lock(&finish); //locks finish mutex to ensure exclusive access
finished++; //count finished threads to measure the execution time
pthread_mutex_unlock(&finish); //unlock finish mutex
pthread_exit(NULL); //finish thread
}
void *consumer(){
/*waits full semaphore > 1 then pick up a number from the buffer (with exclusive access) to check if it's prime*/
long data; //store a buffer number
while(M<10000){
sem_wait(&full); // WAIT FULL
pthread_mutex_lock(&bufferbusy); //locks bufferbusy mutex to ensure exclusive access
for (int i = 0 ; i < N ; i++){ //scrolls the buffer
if (numbers[i] != 0){ //if finds a fited buffer position
data = numbers[i]; //save the number placed at this position
numbers[i] = 0; //clear the buffer position
M++; //increases the consume counter
break; //leave the loop
}
}
pthread_mutex_unlock(&bufferbusy); //unlock bufferbusy mutex
sem_post(&empty); //SIGNAL EMPTY
if(isPrime(data)); //checks if data number is prime
//cout << data << " is prime!" << endl;
//else
//cout << data << " is composite!" << endl;
}
pthread_mutex_lock(&finish); //locks finish mutex to ensure exclusive access
finished++; //count finished threads to measure the execution time
pthread_mutex_unlock(&finish); //unlock finish mutex
pthread_exit(NULL); //finish thread
}
int main (int argc, char *argv[]){
/*___________________________________VARIABLES___________________________________*/
srand (time(NULL)); //seed to measure the execution time
pthread_mutex_init(&bufferbusy,0); //init the bufferbusy mutex with 0
pthread_mutex_init(&finish,0); //init the finish mutex with 0
sem_init(&full, 0, 0); //init the semaphore full(second parameter means that it is only visible by this process)
sem_init(&empty, 0, N); //init the smaphore empty
pthread_t threads[Np+Nc]; //threads declaration
int rc; //handle errors on thread creating
int t; //for loop
/*_______________________________________________________________________________*/
/*_____________________________FILL BUFFER WITH ZEROS____________________________*/
for (int i = 0; i < N; i++) //scrolls the buffer
numbers[i] = 0; //fill all positions with 0
/*_______________________________________________________________________________*/
/*________________________CREATE AND EXECUTE MULTITHREADS________________________*/
clock_t tStart = clock(), tFinish; //start timer
for(t=0; t<Np; t++){ //for each Np
rc = pthread_create(&threads[t], NULL, producer, NULL); //creates a producer thread
if (rc){ //handle error on thread creating
cout << "ERROR; return code from pthread_create() is" << rc << endl;
exit(-1);
}
}
for(t=Np; t<Np+Nc; t++){ //for each Nc
rc = pthread_create(&threads[t], NULL, consumer, NULL); //create a consumer thread
if (rc){ //handle error on thread creating
cout << "ERROR; return code from pthread_create() is" << rc << endl;
exit(-1);
}
}
while (finished < Np+Nc); //blocking wait until all threads have finished
tFinish = clock(); //stop timer
sem_destroy(&full); //semaphore destructor
sem_destroy(&empty); //semaphore destructor
pthread_mutex_destroy(&bufferbusy); //mutex destructor
pthread_mutex_destroy(&finish); //mutex destructor
cout << "Done!" << endl;
cout << "Execution time:" << (double)(tFinish - tStart)/CLOCKS_PER_SEC << endl;
pthread_exit(NULL); //finish last thread
/*_______________________________________________________________________________*/
}
It's already working. Just add a sem_post() before exiting each thread to allow other threads exiting is enough to fix the problem.

I am trying to have the number of threads requested print through each pass of my for loop in the thread_func call

I am using a Ubuntu 64 bit VMWare virtual machine in a Windows 7 environment. The code needs to print each thread[i] for each pass on the for loop of thread_fuc. It is only printing the first tread during each for loop pass.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
int i; // loop control variable
int *id; // array used to pass parameter ofid
int nThreads; // #threads
int turn; // turn points which thread should run
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // a lock for the critical section
pthread_cond_t cond[100]; // array condition variable[nThreads]
pthread_t tid[100]; // pointer to an array of thread identifiers
void *thread_func(void *arg)
{
int id = ((int *) arg)[0]; // this thread's identifier
int loop;
// printf("Thread id is %d\n", id);
printf("The value of turn(before for) is %d\n", turn);
printf("The value of id(before for) is %d\n", id);
for (loop = 0; loop < 10; loop++)
{ // repeat 10 times
// enter the critical section
//<You must insert code here>
pthread_mutex_lock(&mutex);
printf("The value of turn(for) is %d\n", turn);
printf("The value of id(for) is %d\n", id);
while (turn != id)
{
// wait until the (id - 1)th thread signals me.
printf("The value of turn(while) is %d\n", turn);
printf("The value of id(while) is %d\n", id);
// pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond[id], &mutex);
// pthread_cond_signal(&cond[i]);`enter code here`
// pthread_cond_signal(&cond[i]);
// pthread_mutex_unlock(&mutex);
}
if (id == 0)
printf("************** starting turn %d ***************\n", loop);
printf("thread[%d] got %dth turn \n", id, loop);
// signal the next thread
// leave the critical section
//<You must insert code here>
// pthread_mutex_lock(&mutex);
// pthread_cond_wait(&cond[id],&mutex);
pthread_cond_signal(&cond[i]);
pthread_mutex_unlock(&mutex);
}
}
int main(int argc, char *argv[])
{ // validate arguments
if (argc != 2)
{
printf("usage: lab2 #threads\n");
return -1;
}
nThreads = atoi(argv[1]);
if ((nThreads < 1) || (nThreads > 100))
{
printf("usage: proj2 #threads\n");
printf("where #threads >= 1 and <=100\n");
return -1;
}
pthread_mutex_init(&mutex, NULL );
turn = 0; // turn points which thread should run
for (i = 0; i < nThreads; i++)
{ // start a give number (nThreads) of threads.
id = (int*) malloc(sizeof(int));
id[0] = i;
pthread_cond_init(&cond[i], NULL );
pthread_create(&tid[i], NULL, thread_func, (void *) id);
}
pthread_cond_signal(&cond[0]);
for (i = 0; i < nThreads; i++) // wait for all the child threads.
pthread_join(tid[i], NULL );
}
while ( turn != id ) {
//wait until the (id - 1)th thread signals me.
printf("The value of turn(while) is %d\n", turn);
printf("The value of id(while) is %d\n", id);
//pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond[id],&mutex);
//pthread_cond_signal(&cond[i]);`enter code here`
//pthread_cond_signal(&cond[i]);
//pthread_mutex_unlock(&mutex);
}
This part of code prevents other threads to run. They are getting blocked in conditional wait.
The field turn will be always 0. So except first thread all other threads will be blocked in cond wait. Also conditional signal was not properly given for these threads.
pthread_cond_signal(&cond[i]);
i value will be zero and it won't signal other threads.
I finally go this to work. Part of the problem was using the the globally defined variable i, and the mechanism used to advance the counter turn in the function thread_func. Here is the reworked code for the function thread_func.
void *thread_func( void *arg ) {
int id = ((int *)arg)[0]; // this thread's identifier
int loop;
for ( loop = 0; loop < 10; loop++ ) { // repeat 10 times
// enter the critical section
//<You must insert code here>
pthread_mutex_lock(&mutex);
while ( turn != id ) {
// wait until the (id - 1)th thread signals me.
pthread_cond_wait(&cond[id],&mutex);
}
if (id==0) printf("************** starting turn %d ***************\n",loop);
printf( "thread[%d] got %dth turn \n", id, loop)
// signal the next thread
// leave the critical section
//<You must insert code here>
turn = (id + 1) % nThreads;
pthread_cond_signal(&cond[turn]);
pthread_mutex_unlock(&mutex);
}
}

parallel running of threads unreliable behaviour

I've wrote the following program. I expect that this function print 1, 2 sequentially but
the program waits some time(for example 10 sec) and then prints all of the result.
here is the code:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
void *thread_function(void *arg);
char message[] = "Hello World";
int run_now = 1;
int main()
{
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_create(&a_thread, NULL, thread_function, (void *)message);
if (res != 0)
{
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
int print_count1 = 0;
while(print_count1++ < 20)
{
if (run_now == 1)
{
printf("1");
run_now = 2;
}
else
{
sleep(1);
}
}
printf("\nWaiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
if (res != 0)
{
perror("Thread join failed");
exit(EXIT_FAILURE);
}
printf("Thread joined. \n");
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg)
{
int print_count2 = 0;
while(print_count2++ < 20)
{
if (run_now == 2)
{
printf("2");
run_now = 1;
}
else
{
sleep(1);
}
}
}
i expect to 1, 2 be printed every 1 seconds, but program is waiting some times and then prints all of the string entirely. can anybody tell me what's the reason?
int run_now is accessed concurrently and therefore its access needs to be protected.
To do so use a mutex for example:
...
int run_now = 1;
pthtread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int main()
{
...
while(print_count1++ < 20)
{
pthread_mutex_lock(&mutex);
int run_now_equals_1 = (run_now == 1);
if (run_now_equals_1)
{
printf("1");
run_now = 2;
}
pthread_mutex_unlock(&mutex);
if (!run_now_equals_1)
{
sleep(1);
}
}
...
}
void *thread_function(void *arg)
{
int print_count2 = 0;
while(print_count2++ < 20)
{
pthread_mutex_lock(&mutex);
int run_now_equals_2 = (run_now == 2);
if (run_now_equals_2)
{
printf("2");
run_now = 1;
}
pthread_mutex_unlock(&mutex);
if (!run_now_equals_2)
{
sleep(1);
}
}
}
Well, there are a few problems with your program. First, printf may buffer things internally, so you won't see them. This is probably what you refer to. You need to fflush stdout after each printf. The more serious problem is that your program is wrong, as it uses a non-atomic, non-volatile variable for communication.
In your thread_function, the compiler is free to move the load of run_now out of the loop and only work with a register copy, hence the loop won't ever notice that another thread changed the value in memory. You should always use atomic intrinsics to access shared variables like this.
Use fprintf(stderr,"...") instead of printf, or add a fflush(stdout) after each printf.
This is because stout is flushed only when OS decides to flush it, while stderr is flushed as soon as fprintf is called.

Thread Termination Condition

I'm writing a producer-consumer thread program in C. Everything in my program is working perfectly with one major exception. When I have more than one consumer thread, which is pretty much always, only the first consumer thread will actually terminate. I've tried absolutely everything that I can think of, but the problem persists. Here's my code, with the guts of it stripped out, so that you can see just the part that is relevant.
I can see from my output that both of the termination condition variables become zero, which is of course why the first consumer thread terminates. But why don't the other consumer threads also terminate?
Thank you!
sem_t full, empty, mutex;
int threads;
int to_consume;
FILE* inputfp[5];
FILE* outputfp = NULL;
char in[BUF];
void* p(void* inpFile) {
while (fscanf(inpFile, FMTSTRING, in) > 0) {
sem_wait(&empty);
sem_wait(&mutex);
// production code here
to_consume++;
sem_post(&mutex);
sem_post(&full);
}
fclose (inpFile);
sem_wait(&mutex);
threads--;
sem_post(&mutex);
return NULL;
}
void* c() {
int continuing = 1;
while (continuing) {
sem_wait(&full);
sem_wait(&mutex);
//consumption code here
to_consume--;
fprintf("%d %d\n", threads, to_consume); //these both go to zero by the end
if ( (threads <= 0) && (to_consume <= 0) ) {
continuing = 0;
}
sem_post(&mutex);
sem_post(&empty);
}
return NULL;
}
int main (int argc, char* argv[]) {
int i;
int con_threads;
con_threads = 3;
to_consume = 0;
pthread_t *pr_thread[argc-2];
pthread_t *con_thread[2];
sem_init(&full, 0, 0);
sem_init(&empty, 0, 50);
sem_init(&mutex, 0, 1);
for (i = 0; i < (argc-2); i++) {
pr_thread[i] = (pthread_t *) malloc(sizeof(pthread_t));
inputfp[i] = fopen(argv[i+1], "r");
int rc = pthread_create (pr_thread[i], NULL, p, inputfp[i]);
sem_wait(&mutex);
threads++;
sem_post(&mutex);
}
outputfp = fopen(argv[(argc-1)], "wb");
for (i = 0; i con_threads 3; i++) {
con_thread[i] = (pthread_t *) malloc(sizeof(pthread_t));
int rc = pthread_create (con_thread[i], NULL, c, NULL);
}
for (i = 0; i < (argc - 2); i++) {
pthread_join(*pr_thread[i], 0);
free(pr_thread[i]);
}
for (i = 0; i con_threads 3; i++) {
fprintf(stderr, "About to close consumer thread %d.\n", i);
pthread_join(*res_thread[i], 0);
fprintf(stderr, "Consumer thread %d closed successfully.\n", i);
free(res_thread[i]);
}
printf ("About to close the output file.\n");
/* Close the output file */
fclose (outputfp);
return EXIT_SUCCESS;
}
I think your problem is that you don't post full again when the first consumer detects that there are no threads left, so the second consumer is waiting on full but the signal will never arrive. You may need a count of the consumers, though for a first pass (proof of concept), you can leave full with a post that is never read.

Resources