I have a program which is creating two threads but all of this is done in a single c program here is the code
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
void * thread1()
{
int i=0;
while(1)
{
printf("%d Hello!!\n", i);
i++;
}
}
void * thread2()
{
int j;
while(1)
{
printf("%d How are you?\n", j);
j++;
}
}
int main()
{
pthread_t tid1,tid2;
pthread_create(&tid1, NULL, thread1, NULL);
pthread_create(&tid2, NULL, thread2, NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
return 0;
}
now if
void * thread1()
{
int i=0;
while(1)
{
printf("%d Hello!!\n", i);
i++;
}
}
is defined in another program for example mythread1.c
and
void * thread2()
{
int j;
while(1)
{
printf("%d How are you?\n", j);
j++;
}
}
is defined in another c program for example mythread2.c
then how can i call these in my test.c program
test.c
int main()
{
pthread_t tid1,tid2;
pthread_create(&tid1, NULL, thread1, NULL);
pthread_create(&tid2, NULL, thread2, NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
return 0;
}
Please guide me is there any way to do this using Linux system call!
Related
My task is to make a game simulation that uses threads to simulate work. If the thread's been given command to do another work it should pause it's first work and start the new work. How to implement it in C? I've tried with separate function for the input and signaling a condition variable but when it enters the giveCommand() function it just waits for input.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
char command;
pthread_mutex_t mutex;
pthread_cond_t condVar;
void giveCommand()
{
scanf("%c", command);
pthread_cond_signal (&condVar);
return;
}
void *thread(void *N)
{
char c;
do
{
pthread_mutex_lock(&mutex);
//do its work
pthread_cond_timedwait(&condVar, &mutex, 500000);// if command hasn't been given, continue work
pthread_mutex_unlock(&mutex);
pthread_cond_init(&condVar, NULL);
while(giveCommand());
}
}
int main()
{
int i;
int error;
pthread_t threads[NUM_THREADS];
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&condVar, NULL);
while(1)
{
for (i = 0; i < NUM_THREADS; i++)
{
error = pthread_create(&threads[i], NULL, simulateWorker, NULL);
if (error != 0) printf("Error creating thread!");
}
for (i = 0; i < NUM_THREADS; i++)
{
error = pthread_join(threads[i], NULL);
if (error != 0) printf("Error joining thread!");
}
pthread_mutexattr_destroy(&mutex);
}
return 0;
}
I have two functions f1() and f2() I want f1() and f2() to execute
alternately, without using a loop: Not like this : loop {
f1();
f2(); }
I just want to use thread method My code is below:
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<semaphore.h>
void *f1(void *vargp);
void *f2(void *vargp);
static sem_t mutex;
int main(int argc, char **argv) {
pthread_t tid1, tid2;
sem_init(&mutex, 0, 1);
pthread_create(&tid1, NULL, f1, NULL);
pthread_create(&tid2, NULL, f2, NULL);
sleep(100);
return 0;
}
void *f1(void *vargp) {
pthread_detach(pthread_self());
while (1) {
sem_wait(&mutex);
printf("In f1\n");
sleep(1);
sem_post(&mutex);
}
return NULL;
}
void *f2(void *vargp) {
pthread_detach(pthread_self());
while(1) {
sem_wait(&mutex);
printf("In f2\n");
sleep(1);
sem_post(&mutex);
}
return NULL;
}
The result always prints "In f1" What should I do ?
I am writing a multi-threaded application that reads a file and seeks for a word in chunks of it a thread has in memory.
A thread needs to asynchronously close other threads looking for that word if it is first to find it.
The problem is when a word is found and other threads are being closed the program does not terminate (in 6 out of 10 executions). I have checked in gdb that one thread does not exit. It happens even when I do not call waitforthreads(n_threads).
// [...]
FILE* f;
pthread_mutex_t mutex;
pthread_t* threads;
int n_threads;
int allread;
// [...]
int main(int argc, char* argv[]) {
// [...]
threads = (pthread_t*) calloc(n_threads, sizeof(pthread_t));
pthread_mutex_init(&mutex, NULL);
runthreads(f, word, n_threads, n_records);
waitforthreads(n_threads);
pthread_mutex_destroy(&mutex);
// [...]
}
void runthreads(FILE* f, char* w, int n_threads, int n_records) {
struct targs_t args = {w, n_records};
for (int i=0; i<n_threads; i++)
pthread_create(&threads[i], NULL, findword, (void*) &args);
}
void waitforthreads(int N) {
for (int i=0; i<N; i++)
if(pthread_join(threads[i], NULL))
exit_(6);
}
void* findword(void* arg) {
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
struct targs_t* args = (struct targs_t*) arg;
int max_length = args->n_records * sizeof(record_t);
record_t* records = malloc(max_length);
int found = 0;
while (!allread && !found) {
pthread_mutex_lock(&mutex);
// allread is being set in the function below
// if the whole file has been read
readRecords((char*) records, args->n_records, f);
pthread_mutex_unlock(&mutex);
for (int i=0; i<args->n_records; i++)
if (strlen(records[i].text) == 0) break;
else if (strstr(records[i].text, args->word) != NULL) {
notifyfound(pthread_self(), records[i].id);
found = 1;
break;
}
}
free(records);
return NULL;
}
void notifyfound(pthread_t tid, int id) {
printf("Found: %d (%ld)\n", id, (long) tid);
for (int i=0; i<n_threads; i++)
if (threads[i] && !pthread_equal(threads[i], tid)) {
printf(" closing %ld\n", (long) threads[i]);
pthread_cancel(threads[i]);
}
printf(" finished closing\n");
}
This has to do with cancellation points, although the specifics are hard to come by since you haven't shared a minimal example. My diagnosis is either
6/10 times you have at least one thread waiting for a mutex, and other one in readRecords, which will cancel and not free the mutex. Setup cancellation handlers with pthread_cleanup_push and pthread_cleanup_pop which will free your mutex, and read the manual for pthread_cancel. See related pthread_cleanup_push causes Syntax error for some references.
Some of your threads are not detecting the cancellation - try using pthread_testcancel to setup a guaranteed cancellation point.
Here is some code that fixes these sorts of problems, by adding a cancellation check and mutex cleanup.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
FILE* f;
pthread_mutex_t mutex;
pthread_t* threads;
int n_threads = 3;
int allread;
long int count = 0;
int *thread_ids;
int global_quit = 0;
#define MAX 99999
void waitforthreads(int N) {
printf("waiting for %d threads\n", N);
for (int i=0; i<N; i++)
{
printf("thread %d | %d\n", i, threads[i]);
if(pthread_join(threads[i], NULL))
{
printf("problem\n");
exit(6);
}
}
printf("done.\n");
}
void notifyfound(pthread_t tid, int count) {
printf("%d | %d got big number\n", count, pthread_self());
for (int i=0; i<n_threads; i++)
if (threads[i] && !pthread_equal(threads[i], tid)) {
printf(" closing '%ld'\n", (long) threads[i]);
pthread_cancel(threads[i]);
}
global_quit = 1;
printf(" finished closing\n");
}
void waiting_thread_cleanup(void *arg)
{
pthread_mutex_unlock((pthread_mutex_t *)arg);
}
void* do_thing(void* arg) {
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
int* id = (int *)arg;
int quit = 0;
while (!allread) {
pthread_mutex_lock(&mutex);
pthread_cleanup_push(waiting_thread_cleanup, (void *)&mutex); /* must be paired with pop. */
if(count++==MAX)
{
notifyfound(pthread_self(), *id);
quit=1;
}
else if(count % 10000 == 0)
printf("[%d] - %d\n", *id, count);
pthread_testcancel(); /* required to allow for the cancel to ever be 'detected' other functions are sufficient as well. */
pthread_mutex_unlock(&mutex);
pthread_cleanup_pop(1); /* if this isn't here, this will occassionally hand because the mutex isn't freed. */
if(quit==1)
{
printf("%d | %d quitting\n", *id, pthread_self());
break;
}
}
return NULL;
}
void runthreads(FILE* f, int n_threads) {
for (int i=0; i<n_threads; i++)
pthread_create(&threads[i], NULL, do_thing, &(thread_ids[i]));
}
int main(int argc, char* argv[]) {
threads = (pthread_t*) calloc(n_threads, sizeof(pthread_t));
thread_ids = (int*) calloc(n_threads, sizeof(int));
for(int i=0;i<n_threads;i++)
thread_ids[i] = i;
pthread_mutex_init(&mutex, NULL);
runthreads(f, n_threads);
waitforthreads(n_threads);
pthread_mutex_destroy(&mutex);
}
I'm trying to write a program that uses 3 threads with a shared memory. the shared memory is an array with 101 values. the first value shared memory[0](initialized to 0) is status value which determines which operation should take place. the three threads do
The first one should fill the shared memory array with 100 random values. and set the status value to 1.
The second should print the product of the 100 random values (from index 1 to 100). and set the status value to 2.
The third should print the average of the 100 random variables. and set the status value to 0. so that thread one fill the shared memory with different random variables.
this is my code
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
unsigned int product=0;
float avg=0;
int* shared_memory;
int status=0;
void productAllThread();
void averageAllThread();
void *parentProcess();
void *prodAll();
void *avgAll();
void initializeArray();
int main(int argc, const char * argv[])
{
time_t t;
key_t key = 9876;
// Create shared memory area
int shm_id = shmget(key, sizeof(int)*101, IPC_CREAT | 0666);
// initialize the random variable
srand((unsigned) time(&t));
// Create shared memory
shared_memory=shmat(shm_id, NULL, 0);
//create threads
pthread_t tid1, tid2, tid3;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid1, &attr, parentProcess, NULL);
pthread_create(&tid2, &attr, prodAll, NULL);
pthread_create(&tid3, &attr, avgAll, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_join(tid3, NULL);
return 0;
}
void initializeArray() {
shared_memory[0]=0;
status=shared_memory[0];
int i= 0;
printf("Initial Array:{");
for(i=1; i<100; i++)
{
shared_memory[i]=rand()% 50;
printf("%d,", shared_memory[i]);
}
printf("}\n");
}
void *parentProcess()
{
while(1)
{
status=shared_memory[0];
if(status==0) {
// initialize array
initializeArray();
shared_memory[0]=1;
} else {
sleep(10);
}
}
}
void averageAllThread() {
while(1) {
status=shared_memory[0];
if(status==2)
{
avgAll();
wait(NULL);
printf("Avg:%.2f\n", avg);
shared_memory[0]=0;
} else {
sleep(5);
}
}
}
void productAllThread() {
while(1){
status=shared_memory[10];
if (status==1)
{
prodAll();
wait(NULL);
printf("Sum:%d\n",product);
shared_memory[0]=2;
} else {
sleep(5);
}
}
}
void *prodAll()
{
while(1){
int i=1;
product=0;
for(i=1; i<100; i++)
{
product=product+shared_memory[i];
}
}
}
void *avgAll()
{
while(1){
int i=0;
avg=0;
for(i=1; i<100; i++)
{
avg=avg+shared_memory[i];
}
avg=avg/100;
}
}
when I run it in the terminal, it gives me this error
"Segmentation fault: 11"
what might cause this type of errors? If this error is fixed will the program work fine to do the job I want it to do?
I found a few problems in your program:
You are calling the wrong functions to start your threads:
pthread_create(&tid1, &attr, parentProcess, NULL);
pthread_create(&tid2, &attr, prodAll, NULL);
pthread_create(&tid3, &attr, avgAll, NULL);
Should be:
pthread_create(&tid1, &attr, parentProcess, NULL);
pthread_create(&tid2, &attr, productAllThread, NULL);
pthread_create(&tid3, &attr, averageAllThread, NULL);
You have a few calls to wait() like this:
wait(NULL);
You should remove all of them.
The while loops in avgAll() and prodAll() should be removed since there are already while loops in the callers of those functions.
The call to srand() should be made from parentProcess() otherwise it might not affect the rand() calls in that thread.
in this example code below, where is the "critical section" exatly?. after "sem_wait()" ?
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
void * thread_snd(void *arg);
void * thread_rcv(void *arg);
sem_t bin_sem;
int number=0;
char thread1[]="A Thread";
char thread2[]="B Thread";
char thread3[]="C Thread";
int main(int argc, char **argv)
{
pthread_t t1, t2, t3;
void *thread_result;
int state;
state = sem_init(&bin_sem, 0, 0);
pthread_create(&t1, NULL, thread_snd, &thread1);
pthread_create(&t2, NULL, thread_rcv, &thread2);
pthread_create(&t3, NULL, thread_rcv, &thread3);
pthread_join(t1, &thread_result);
pthread_join(t2, &thread_result);
pthread_join(t3, &thread_result);
printf("number : %d \n", number);
sem_destroy(&bin_sem);
return 0;
}
void * thread_snd(void * arg)
{
int i;
for(i=0; i<4; i++)
{
while(number != 0)
sleep(1);
number++;
printf("%s, number : %d \n", (char*)arg, number);
sem_post(&bin_sem);
}
}
void * thread_rcv(void * arg)
{
int i;
for(i=0; i<2; i++)
{
sem_wait(&bin_sem);
number--;
printf("%s, number : %d \n", (char*)arg, number);
}
}
There actually is no "critical section" in the provided code, there is only "sync point", and yes that is realized with the semaphore. The critical section can also be implemented with semaphore, but then the thread must use both sem_wait() and sem_post() but in most cases mutexes are used for critical sections (if only one thread is ever supposed to enter it).