What is causing the thread to wait? - c

This code isn't finished yet so right know it should just print the lines out. but i cant figure out whats locking the first P( direc_sem );
#include <sys/types.h>
#include <sys/ipc.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include "sem_ops.h"
#include <semaphore.h>
#define MAXCARS 5
#define MAXWAIT 20
#define CROSSINGTIME 4
int G_direction = 0, direc_sem, car_E;
int carNum;
int retVal=0, lower = 0, upper = 1;
int car_rid[MAXCARS];
pthread_t threads[MAXCARS];
const char* printRandoms()
{
int num = (rand() % (upper - lower + 1)) + lower;
if (num == 0){
//left headed west
return "west";
}else return "east";
//return num;
}
void *car(void *arg) {
int carNum = (int)(intptr_t)arg; //what car is it
const char* direction = printRandoms(); //random direction
printf(" car no %d is idling, planning to go %s \n",carNum, direction);// test print
sleep( rand() % MAXWAIT ); // wait a random amounnt of time
//P( reader_sem );
//readers++;
//if( readers == 1 )
// P( counter_sem );
//V( reader_sem );
P( direc_sem );
if (G_direction >=0){
G_direction++;//->> move on to bridge
if (G_direction == 1){//if first car on bridge lock other traffic
P(car_E);
}else {
printf("stuck");
}
}
V(direc_sem);
printf("car no %d goes on the bridge heading %s \n", carNum,direction);
sleep(CROSSINGTIME);
printf("car no %d goes off the bridge heading %s \n", carNum, direction);
P(direc_sem);
G_direction--;//->> move off the bridge
if (G_direction == 0){//if last car on bridge unlock other traffic
V(car_E);
}
V(direc_sem);
//bridge no longer empty
// printf("W car# %d => %d\n", carNum, G_direction);//print test
// }// wait till westbound car is free
}
void Truck(){
}
int main( void ){
direc_sem = semtran( IPC_PRIVATE );
car_E = semtran( IPC_PRIVATE );
for (int i = 0; i < MAXCARS; i++){
retVal = pthread_create(&threads[i], NULL,car ,(void *)(intptr_t)i);
if(retVal!=0){
printf("pthread_create failed in %d_th pass\n",i);
exit(EXIT_FAILURE);
}
}
for (int i = 0; i < MAXCARS; i++){
retVal = pthread_join(threads[i], NULL);
if(retVal!=0){
printf("pthread_join failed in %d_th pass\n",i);
exit(EXIT_FAILURE);
}
}
//sem_destroy(&carLock);
return 0;
}

compiled with wrong file definitely been at this too long thank you

Related

why dose this thread code output differently?

I'm trying to wrap my head wrap my head around threads, I would like to have only one direction of car on the bridge at a time at at the moment only east bound cars work. i commented out line 37's randomized+ direction function and when substituting in "east"code works as expected, but when running "west" it hold and theres my issue. Any help appreciated.
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/sem.h>
#include <semaphore.h>
#define MAXCARS 5
#define MAXWAIT 10
#define CROSSINGTIME 2
int G_direction = 0;
int carNum;
int retVal=0, lower = 0, upper = 1;
int car_rid[MAXCARS];
pthread_t threads[MAXCARS];
sem_t direc_sem, car_E, car_W,bridge_sem;
const char* printRandoms() ///randomise the cars direction
{
int num = (rand() % (upper - lower + 1)) + lower;
if (num == 0){
//left headed west
return "west";
}else return "east";
//return num;
}
void *car(void *arg) {
int carNum = (int)(intptr_t)arg; //what car is it
const char* direction = "west";//printRandoms(); //random direction
printf("car no %d is idling, planning to go %s \n",carNum, direction);// test print
sleep( rand() % MAXWAIT ); // wait a random amounnt of time
sem_wait(&direc_sem);//isolate the direction value
if(strcmp(direction,"west") == 0){
if (G_direction > 0){//g_direction 1 = one car headed east 2 two headed east
sem_wait(&car_E);//if traffic flow is in the wrong direction wait for the semaphore
}
G_direction--;//->> move ON the bridge
if (G_direction == -1){//if last car on bridge lock west bound traffic
sem_wait(&car_W);
}
}
sem_post(&direc_sem);
sem_wait(&direc_sem);//isolate the direction value
if(strcmp(direction,"east") == 0){
if (G_direction < 0){//g_direction 1 = one car headed east 2 two headed east
sem_wait(&car_W);//if traffic flow is in the wrong direction wait for the semaphore
}
G_direction++;//->> move ON the bridge
if (G_direction == 1){//if last car on bridge lock west bound traffic
sem_wait(&car_E);
}
}
sem_post(&direc_sem);
printf("car no %d goes ON the bridge heading %s \n", carNum,direction);
sleep(CROSSINGTIME);
printf("car no %d goes OFF the bridge heading %s \n", carNum, direction);
sem_wait(&direc_sem);//isolate the direction value
if(strcmp(direction, "west") == 0){
G_direction++;//->> move OFF the bridge
if (G_direction == 0){//if last car on bridge unlock other traffic
sem_post(&car_W);
}
}
sem_post(&direc_sem);
sem_wait(&direc_sem);//isolate the direction value
if(strcmp(direction,"east") == 0){
G_direction--;//->> move off the bridge
if (G_direction == 0){//if last car on bridge unlock other traffic
sem_post(&car_E);
}
}
sem_post(&direc_sem);
}
int main( void ){
sem_init(&direc_sem, 0, 1);
sem_init(&car_E, 0, 1);
sem_init(&bridge_sem, 0, 1);
for (int i = 0; i < MAXCARS; i++){
retVal = pthread_create(&threads[i], NULL,car ,(void *)(intptr_t)i);
if(retVal!=0){
printf("pthread_create failed in %d_th pass\n",i);
exit(EXIT_FAILURE);
}
}
for (int i = 0; i < MAXCARS; i++){
retVal = pthread_join(threads[i], NULL);
if(retVal!=0){
printf("pthread_join failed in %d_th pass\n",i);
exit(EXIT_FAILURE);
}
}
//sem_destroy(&carLock);
return 0;
}

threads waiting unexpectedly not sure whats causing

I'm wanting to stop traffic of opposing direction from crashing om the bridge. if the randomized get all cars heading east it works fine. It hangs on west bound traffic. im have a feeling that there's a better was to stop threads from colliding as im using so many sem_post() and sem_wait()
any suggestions or help welcome, still just learning threads so i expect to be missing something.
eventually i want randomised traffic from both direction as well as trucks that need the bridge all to them selves where as cars can share so long as the traffic flow is the same.
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/sem.h>
#include <semaphore.h>
#define MAXCARS 5
#define MAXWAIT 10
#define CROSSINGTIME 2
int G_direction = 0;
int carNum;
int retVal=0, lower = 0, upper = 1;
int car_rid[MAXCARS];
pthread_t threads[MAXCARS];
sem_t direc_sem, car_E, car_W,bridge_sem;
const char* printRandoms() ///randomise the cars direction
{
int num = (rand() % (upper - lower + 1)) + lower;
if (num == 0){
//left headed west
return "west";
}else return "east";
//return num;
}
void *car(void *arg) {
int carNum = (int)(intptr_t)arg; //what car is it
const char* direction = printRandoms(); //random direction
printf(" car no %d is idling, planning to go %s \n",carNum, direction);// test print
sleep( rand() % MAXWAIT ); // wait a random amounnt of time
sem_wait(&direc_sem); //isolate the direction value
if(direction == "west"){
if (G_direction > 0){//g_direction -1 = one car headed west -2 two headed west
sem_wait(&car_E);//if traffic flow is in the wrong direction wait for the semaphore
}
G_direction--;//->> move ON the bridge
if (G_direction == -1){//if last car on bridge lock east bound traffic
sem_wait(&car_W);
}
}
sem_post(&direc_sem);
sem_wait(&direc_sem);//isolate the direction value
if(direction == "east"){
if (G_direction < 0){//g_direction 1 = one car headed east 2 two headed east
sem_wait(&car_W);//if traffic flow is in the wrong direction wait for the semaphore
}
G_direction++;//->> move ON the bridge
if (G_direction == 1){//if last car on bridge lock west bound traffic
sem_wait(&car_E);
}
}
sem_post(&direc_sem);
printf("car no %d goes ON the bridge heading %s \n", carNum,direction);
sleep(CROSSINGTIME);
printf("car no %d goes OFF the bridge heading %s \n", carNum, direction);
sem_wait(&direc_sem);//isolate the direction value
if(direction == "west"){
G_direction++;//->> move OFF the bridge
if (G_direction == 0){//if last car on bridge unlock other traffic
sem_post(&car_W);
}
}
sem_post(&direc_sem);
sem_wait(&direc_sem);//isolate the direction value
if(direction == "east"){
G_direction--;//->> move off the bridge
if (G_direction == 0){//if last car on bridge unlock other traffic
sem_post(&car_E);
}
}
sem_post(&direc_sem);
}
int main( void ){
sem_init(&direc_sem, 0, 1);
sem_init(&car_E, 0, 1);
sem_init(&bridge_sem, 0, 1);
for (int i = 0; i < MAXCARS; i++){
retVal = pthread_create(&threads[i], NULL,car ,(void *)(intptr_t)i);
if(retVal!=0){
printf("pthread_create failed in %d_th pass\n",i);
exit(EXIT_FAILURE);
}
}
for (int i = 0; i < MAXCARS; i++){
retVal = pthread_join(threads[i], NULL);
if(retVal!=0){
printf("pthread_join failed in %d_th pass\n",i);
exit(EXIT_FAILURE);
}
}
//sem_destroy(&carLock);
return 0;
}```

Squaring numbers with multiple threads

I am trying to square the numbers 1 - 10,000 with 8 threads. To clarify, I want the 1st thread to do 1^2, 2nd thread to do 2^2, ..., 8th thread to do 8^2, first thread to do 9^2... etc. The problem I am having is that instead of the above happening, each thread computes the squares of 1-10,000.
My code is below. I have marked sections that I'd rather those answering do not modify. Thanks in advance for any tips!
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <pthread.h>
#define NUMBER_OF_THREADS 8
#define START_NUMBER 1
#define END_NUMBER 10000
FILE *f;
void *sqrtfunc(void *tid) { //function for computing squares
int i;
for (i = START_NUMBER; i<=END_NUMBER; i++){
fprintf(f, "%lu squared = %lu\n", i, i*i);
}
}
int main(){
//Do not modify starting here
struct timeval start_time, end_time;
gettimeofday(&start_time, 0);
long unsigned i;
f = fopen("./squared_numbers.txt", "w");
//Do not modify ending here
pthread_t mythreads[NUMBER_OF_THREADS]; //thread variable
long mystatus;
for (i = 0; i < NUMBER_OF_THREADS; i++){ //loop to create 8 threads
mystatus = pthread_create(&mythreads[i], NULL, sqrtfunc, (void *)i);
if (mystatus != 0){ //check if pthread_create worked
printf("pthread_create failed\n");
exit(-1);
}
}
for (i = 0; i < NUMBER_OF_THREADS; i++){
if(pthread_join(mythreads[i], NULL)){
printf("Thread failed\n");
}
}
exit(1);
//Do not modify starting here
fclose(f);
gettimeofday(&end_time, 0);
float elapsed = (end_time.tv_sec-start_time.tv_sec) * 1000.0f + \
(end_time.tv_usec-start_time.tv_usec) / 1000.0f;
printf("took %0.2f milliseconds\n", elapsed);
//Do not modify ending here
}

Pass an int array in pthread function in C

I'm coding a multithreaded program for exercise. Given an array (100 positions) of random numbers, I have to divide it by 5 arrays and give them to 5 pthreads in order to find the maximum and return these values to the main function that find the maximum between them. These is my code so far:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define NUM_THREADS 5
#define DIM_VETTORE 100
void *Calcola_max(void* args){
}
int main(){
int vettore[DIM_VETTORE];
int t;
int i;
srand(time(NULL));
/*riempio il vettore con numeri random*/
for (i=0; i<DIM_VETTORE; i++){
vettore[i]=rand() % 500 + 1;
printf("Numero in posizione %d: %d\n", i,vettore[i]);
}
/*indico le dimensioni di ogni array splittato*/
int dimensione_split=DIM_VETTORE/NUM_THREADS;
printf("Dimensione degli array splittati: %d\n", dimensione_split);
/*creo tutti i thread*/
pthread_t thread[NUM_THREADS];
for (t=0;t<NUM_THREADS; t++){
printf("Main: creazione thread %d\n", t);
int rc;
rc=pthread_create(&thread[t], NULL, Calcola_max, &vettore);
if (rc) {
printf("ERRORE: %d\n", rc);
exit(-1);
}
}
}
My question are: how can I split the array? And how can I pass each array to each pthread? Thanks in advance
So, I've edited my code but this time it gives me segmentation fault after the pthread creation. IMO I'm wrong to pass the argument of thread function in this way:
...
pthread_create(&thread[t], NULL, Calcola_max, (void *)&start[i]);
...
void *Calcola_max(void *a){
...
s = *(int *)a;
...
Here is my entire code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define NUM_THREADS 5
#define DIM_VETTORE 100
int vettore[DIM_VETTORE];
int start[100];
int max[100]; //vettore dove vanno tutti i minimi calcolati dai pthread
void *Calcola_max(void *a){
int array;
int n=DIM_VETTORE/NUM_THREADS;
int s, i;
int start, stop;
int massimo;
s = *(int *)a;
start = s * n;
if ( s != (NUM_THREADS-1) )
{
stop = start + n;
}
else
{
stop = DIM_VETTORE;
}
massimo=vettore[start];
for (i = start+1; i < stop; i++ )
{
if ( vettore[i] > massimo )
massimo = vettore[i];
}
max[s] = massimo;
//array = (int) a;
int k;
int max=0;
for (k=0; k<DIM_VETTORE; k++){ //qui devo mettere il range corrente del vettore, o mettere uno split di vettore
printf("Massimo corrente: %d\n",max);
if (vettore[k]>max) max=vettore[k];
}
//return(NULL); /* Thread exits (dies) */
pthread_exit;
}
int main(){
//int vettore[DIM_VETTORE];
int massimo; //vettore dei minimi finale in cui opero confronto e calcolo il minimo
int t;
int i, j;
srand(time(NULL));
/*riempio il vettore con numeri random*/
for (i=0; i<DIM_VETTORE; i++){
//int num; //contenitore numero random
vettore[i]=rand() % 500 + 1;
//printf("Numero in posizione %d: %d\n", i,vettore[i]);
}
/*indico le dimensioni di ogni array splittato*/
int dimensione_split=DIM_VETTORE/NUM_THREADS;
printf("Dimensione degli array splittati: %d\n", dimensione_split);
/*creo tutti i thread*/
pthread_t thread[NUM_THREADS];
for (t=0;t<NUM_THREADS; t++){
start[i] = i;
printf("Main: creazione thread %d\n", t);
int rc;
//int pos_vettore;
//for (pos_vettore=0; pos_vettore<100; pos_vettore+20){
rc=pthread_create(&thread[t], NULL, Calcola_max, (void *)&start[i]);
if (rc) {
printf("ERRORE: %d\n", rc);
exit(-1);
}
//}
}
/*joino i threads*/
for (i = 0; i < NUM_THREADS; i++)
pthread_join(thread[i], NULL);
massimo= max[0];
sleep(3);
for (i = 1; i < NUM_THREADS; i++)
if ( max[i] > massimo )
massimo = max[i];
printf("Il massimo รจ: %d\n", massimo);
}
Your pthreads can access the array in your main program easily. You won't need to split the array for that. Just make sure that the pthreads are modifiying different parts of the main array. Use a struct or typedef to pass the relevant information to the pthread functions.
As mentioned, you don't split or copy the array.
Threads share the same regions of memory as the process that creates them, so you could just pass around the array.
If the aim of the game is to find some perf gain from using threads, then you almost certainly don't want to use heap allocated memory.
It's got to be said that there are probably better ways, I would probably look to SIMD or some other SSE extension before threads, but whatever ...
The following example, which has had about 5 minutes thought, and requires better error checking, and verification of the logic (because it's 9am on Sunday), demonstrates how I think the most efficient way to thread the calculations might be.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#define THREADS 5
#define DATA 100
typedef struct _pthread_arg_t {
pthread_t thread;
int *data;
unsigned int end;
int max;
} pthread_arg_t;
void* pthread_routine(void *arg) {
pthread_arg_t *info = (pthread_arg_t*) arg;
int *it = info->data,
*end = info->data + info->end;
while (it < end) {
if (*it > info->max) {
info->max = *it;
}
it++;
}
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
pthread_arg_t threads[THREADS];
int data[DATA],
thread = 0,
limit = 0,
result = 0;
memset(&threads, 0, sizeof(pthread_arg_t) * THREADS);
memset(&data, 0, sizeof(int) * DATA);
while (limit < DATA) {
/* you can replace this with randomm number */
data[limit] = limit;
limit++;
}
limit = DATA/THREADS;
while (thread < THREADS) {
threads[thread].data = &data[thread * limit];
threads[thread].end = limit;
if (pthread_create(&threads[thread].thread, NULL, pthread_routine, &threads[thread]) != 0) {
/* do something */
return 1;
}
thread++;
}
thread = 0;
while (thread < THREADS) {
if (pthread_join(threads[thread].thread, NULL) != 0) {
/* do something */
return 1;
}
thread++;
}
thread = 0;
result = threads[0].max;
printf("result:\n");
while (thread < THREADS) {
printf("\t%d - %d: %d\n",
thread * limit,
thread * limit + limit - 1,
threads[thread].max);
if (threads[thread].max > result) {
result = threads[thread].max;
}
thread++;
}
printf("max\t%d\n", result);
return 0;
}
Notice that this is lock and malloc free, you could probably reduce instructions further with more fiddling ...

C: Using functions from a separate file

Trying to use a bounded buffer from a separate file that I've coded and it seems like that's where the code goes all crazy. Fairly new to C, and I was wondering if I am using the buffer the right way. The concept of instantiation isn't here, so if I just call one of the functions such as bbuff_blocking_insert will the array get initialized? How do I make the appropriate calls in order to get this working?
candy.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include "bbuff.h"
#include <stdbool.h>
#include <time.h>
_Bool stop_thread = false;
typedef struct {
int source_thread;
double time_stamp_in_ms;
} candy_t;
double current_time_in_ms (void) {
struct timespec now;
clock_gettime(CLOCK_REALTIME, &now);
return now.tv_sec * 1000.0 + now.tv_nsec/1000000.0;
}
void* createCandy(void* arg) {
int r;
int factoryNumber = *(int*)arg;
while(!stop_thread) {
r = rand() % 4;
printf("Random Number: %d\n", r);
printf("\tFactory %d ship candy & wait %ds\n", factoryNumber, r);
candy_t *candy = (candy_t*)malloc(sizeof(candy_t));
candy->source_thread = factoryNumber;
candy->time_stamp_in_ms = current_time_in_ms();
bbuff_blocking_insert((void *)candy);
sleep(r);
}
printf("Candy-factory %d done\n", factoryNumber);
return 0;
}
void* extractCandy(void* arg) {
int r;
candy_t* candy;
while(true) {
candy = (candy_t*)bbuff_blocking_extract();
printf("Candy Source Thread: %d\n", candy->source_thread);
r = rand() % 2;
sleep(r);
}
return 0;
}
int main(int argc, char* argv[]) {
//Extract Arguments
if (argc <= 1) {
printf("Insufficient Arguments\n");
exit(-1);
}
int NO_FACTORIES = atoi(argv[1]);
int NO_KIDS = atoi(argv[2]);
int NO_SECONDS = atoi(argv[3]);
bbuff_init();
//Spawn Factory Threads
pthread_t ftids[NO_FACTORIES];
int factoryNumber[NO_FACTORIES];
for (int i = 0; i < NO_FACTORIES; i++) {
factoryNumber[i] = i;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&ftids[i], &attr, createCandy, &factoryNumber[i]);
}
//Spawn Kid Threads
pthread_t ktids [NO_KIDS];
for (int i = 0; i < NO_KIDS; i++) {
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&ktids[i], &attr, extractCandy, NULL);
}
//Wait for Requested Time
for (int i = 0; i < NO_SECONDS; i++) {
sleep(1);
printf("Time %ds\n", i+1);
}
//Stop Factory Threads
stop_thread = true;
for (int i = 0; i < NO_FACTORIES; i++) {
pthread_join(ftids[i], NULL);
}
//Wait until no more candy
while(bbuff_is_data_available()) {
printf("Waiting for all candy to be consumed");
sleep(1);
}
//Stop kid Threads
for (int i = 0; i < NO_KIDS; i++) {
pthread_cancel(ktids[i]);
pthread_join(ktids[i], NULL);
}
//Print Statistics
//Clean up any allocated memory
return 0;
}
bbuff.h
#ifndef BBUFF_H
#define BBUFF_H
#define QUEUE_SIZE 10
void bbuff_init(void);
void bbuff_blocking_insert(void* item);
void* bbuff_blocking_extract(void);
_Bool bbuff_is_data_available(void);
#endif
bbuff.c
#include "bbuff.h"
pthread_mutex_t mutex;
sem_t empty;
sem_t full;
int in = 0;
int out = 0;
int counter = 0;
void* buffer[QUEUE_SIZE];
void bbuff_init(void){
pthread_mutex_init(&mutex, NULL);
sem_init( &empty, 0, QUEUE_SIZE);
sem_init( &full, 0, 0);
}
void bbuff_blocking_insert(void* item) {
sem_wait(&empty);
pthread_mutex_lock(&mutex);
counter++;
buffer[in] = item;
in = (in+1) % QUEUE_SIZE;
pthread_mutex_unlock(&mutex);
sem_post(&full);
}
void* bbuff_blocking_extract(void) {
void* extractedItem;
sem_wait(&full);
pthread_mutex_lock(&mutex);
counter--;
extractedItem = buffer[out];
buffer[out] = NULL;
out = out % QUEUE_SIZE;
pthread_mutex_unlock(&mutex);
sem_post(&empty);
return extractedItem;
}
Output
$ ./candykids 1 1 10
Random Number: 3
Factory 0 ship candy & wait 3s
Candy Source Thread: 0
Time 1s
Time 2s
Random Number: 1
Factory 0 ship candy & wait 1s
Time 3s
Segmentation fault (core dumped)
In bbuff_blocking_extract(),
out = out % QUEUE_SIZE;
Should be:
out = (out+1) % QUEUE_SIZE;

Resources