I am trying to learn how to create threads in c using the pthread library, I am using the following code:
#include <stdlib.h>
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
static int glob = 0;
static sem_t sem;
static void *threadFunc(void *arg) {
int loops = *((int *) arg);
int loc, j;
for (j = 0; j < loops; j++) {
if (sem_wait(&sem) == -1)
exit(2);
loc = glob;
loc++;
glob = loc;
if (sem_post(&sem) == -1)
exit(2);
}
printf("\n%d %d\n",glob/20,glob);
return NULL;
}
int main(int argc, char *argv[]) {
pthread_t t1, t2, t3, t4;
int s;
int loops = 20;
if (sem_init(&sem, 0, 1) == -1) {
printf("Error, init semaphore\n");
exit(1);
}
s = pthread_create(&t1, NULL, threadFunc, &loops);
if (s != 0) {
printf("Error, creating threads\n");
exit(1);
}
s = pthread_create(&t2, NULL, threadFunc, &loops);
if (s != 0) {
printf("Error, creating threads\n");
exit(1);
}
s = pthread_create(&t3, NULL, threadFunc, &loops);
if (s != 0) {
printf("Error, creating threads\n");
exit(1);
}
s = pthread_create(&t4, NULL, threadFunc, &loops);
if (s != 0) {
printf("Error, creating threads\n");
exit(1);
}
s = pthread_join(t1, NULL);
if (s != 0) {
printf("Error, creating threads\n");
exit(1);
}
s = pthread_join(t2, NULL);
if (s != 0) {
printf("Error, creating threads\n");
exit(1);
}
s = pthread_join(t3, NULL);
if (s != 0) {
printf("Error, creating threads\n");
exit(1);
}
s = pthread_join(t4, NULL);
if (s != 0) {
printf("Error, creating threads\n");
exit(1);
}
printf("glob value %d \n", glob);
exit(0);
}
What are the expected values of glob when I try to print them using the print statement in threadFunc? Shuold they be 20,40,60 and 80? When I execute the above program I get different values for glob like, 61, 50, 73 and 80!! or 29,76,78,80? How come? EVerytime I execute I get different values for glob. I think it has something to do with the semaphore but then how can the value for glob decrease like in the first output example I gave you?
Furthermore, what is the purpose for a thread_initiate given to pthread_create? Not threadFunc specifically but in general what do programmers dealing with threads in c generally do using the thread_initiate function passed to pthread_create?
I figured it out, I didn't think about the code properly. The threads are running concurrently so there is no way to decide what the value of glob will be. If two threads are running, the first one might be 5 values into the loop and the second thread might be 2 values which will mean the value of glob is 7. When glob is printed the value will always be greater than a multiple of 20 (for this particular problem).
As for the second part I believe that the starting routine is the code that the thread is going to run.
Thanks to #WhozCraig and #JoachimPileborg for the help!
Related
I wrote a program to learn about thread-specific data on Linux (Linux 3.13.0-24-generic #46-Ubuntu), as following.
I try to print thread id in the destructor function passed to pthread_key_create(), but it seems only sub threads succeed to print, but the main thread didn't print that info.
My question is:
Does the destructor function called right before or after termination of a thread?
The reason why main thread didn't print the info, is it due to the main thread already destroyed?
tsd_test.c
// test of thread-specific data
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
static pthread_once_t once = PTHREAD_ONCE_INIT;
static pthread_key_t tidKey;
static void destructor(void *buf) {
unsigned long *_tid = buf;
printf("destroy, tid: %lu\n", *_tid);
free(buf);
}
static void createKey(void) {
int s = pthread_key_create(&tidKey, destructor);
if(s != 0) {
printf("failed to create key\n");
exit(-1);
}
}
void *store_tid() {
int s;
unsigned long *buf;
// create key
s = pthread_once(&once, createKey);
if(s != 0) {
printf("failed to create key\n");
exit(-1);
}
buf = pthread_getspecific(tidKey);
if(buf == NULL) { // thread call this function for the first time,
buf = malloc(sizeof(unsigned long));
if(buf == NULL) {
printf("failed to allocate memory, %s\n", strerror(errno));
exit(-1);
}
// register buffer to specified key & current thread,
s = pthread_setspecific(tidKey, buf);
if(s != 0) {
printf("failed to setspecific\n");
exit(-1);
}
}
// store tid to buffer,
*buf = (unsigned long)pthread_self();
printf("set tid to: %lu\n", *buf);
return buf;
}
void tsd_test() {
unsigned long *tidp_a = store_tid();
printf("tid - before call another thread: %lu\n", *tidp_a);
int s;
pthread_t t2;
s = pthread_create(&t2, NULL, &store_tid, NULL);
if(s != 0) {
printf("failed to create thread\n");
exit(-1);
}
s = pthread_join(t2, NULL);
if(s != 0) {
printf("failed to join thread\n");
exit(-1);
}
printf("tid - after call another thread: %lu\n", *tidp_a);
}
int main(int argc, char *argv[]) {
tsd_test();
return 0;
}
Compile:
gcc -pthread tsd_test.c
Output:
set tid to: 3076318976
tid - before call another thread: 3076318976
set tid to: 3076315968
destroy, tid: 3076315968
tid - after call another thread: 3076318976
You can see that only the sub thread print "destroy", while the main thread didn't.
The thread destructor is called when the thread exits, not when the process dies i.e. when main() exits, the entire process dies. So destructor will not be called on that.
Call pthread_exit(NULL); either at the end of main() function or at the end tst() function (both are same really). Now, you will see the destructor being called.
Hi im trying to implement faster cat than the one provided.
My current implementation looks like this:
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define BUF_SIZE 1024*1024*1024
char buffer[BUF_SIZE];
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_var2 = PTHREAD_COND_INITIALIZER;
int readed = 0;
/*
Read characters from standard input and saves them to buffer
*/
void *consumer(void *data) {
int r;
while(1) {
//---------CRITICAL CODE--------------
//------------REGION------------------
pthread_mutex_lock(&mutex);
if (readed > 0)
{
pthread_cond_wait(&cond_var2, &mutex);
}
r = read(0, buffer, BUF_SIZE);
readed = r;
pthread_cond_signal(&cond_var);
pthread_mutex_unlock(&mutex);
//------------------------------------
if (r == -1){
printf("Error reading\n");
}
else if (r == 0) {
pthread_exit(NULL);
}
}
}
/*
Print chars readed by consumer from standard input to standard output
*/
void *out_producer(void *data) {
int w;
while(1){
//---------CRITICAL CODE--------------
//-------------REGION-----------------
pthread_mutex_lock(&mutex);
if (readed == 0)
{
pthread_cond_wait(&cond_var, &mutex);
}
w = write(1, buffer, readed);
readed = 0;
pthread_cond_signal(&cond_var2);
pthread_mutex_unlock(&mutex);
//------------------------------------
if (w == -1){
printf("Error writing\n");
}
else if (w == 0) {
pthread_exit(NULL);
}
}
}
What would you suggest to make it faster?
Any ideas?
I was thinking about the BUF_SIZE, what would you think would be optimal size of buffer?
Main just makes the threads:
int main() {
// Program RETURN value
int return_value = 0;
// in - INPUT thread
// out - OUTPUT thread
pthread_t in, out;
// Creating in thread - should read from standard input (0)
return_value = pthread_create(&in , NULL, consumer, NULL);
if (return_value != 0) {
printf("Error creating input thread exiting with code error: %d\n", return_value);
return return_value;
}
// Creating out thread - should write to standard output (1)
return_value = pthread_create(&out, NULL, out_producer, NULL);
if (return_value != 0) {
printf("Error creating output thread exiting with code error: %d\n", return_value);
return return_value;
}
return_value = pthread_join(in, NULL);
return_value = pthread_join(out, NULL);
return return_value;
}
How exactly is adding threads to cat going to make it faster? You can't just throw parallelism at any program and expect it to run faster.
Cat basically just transports every line of input (usually from a file) to output. Since it's important that the lines are in order, you have to use mutual exclusion to avoid racing.
The upper bound of the speed (the fastest that cat can run) in parallel cannot be higher than cat in serial, since every thread must perform the serial actions, along with the cost of synchronization.
I have to wriete program
"Bring to life two threads. First thread must write char 'a' 30000
times second one 'b' 25000 times.
I wrote this program but i do not know this is a good result. I expect first see 30000 times a then b when I use pthread_join(p,NULL). My program write a and b randomaly it is good or not?
#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
pthread_t f,s;
void* a(void *arg)
{
int j;
for(j=0;j<30000;j++) printf("a\n");
return NULL;
}
void* b(void *arg)
{
int u;
for(u=0;u<25000;u++) printf("b\n");
return NULL;
}
int main(void)
{
int i = 0;
int err;
err = pthread_create(&f, NULL, &a, NULL);
if (err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
else
printf("\n Thread created successfully\n");
err = pthread_create(&s, NULL, &b, NULL);
if (err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
else
printf("\n Thread created successfully\n");
pthread_join(f, NULL);
sleep(5);
return 0;
}
I want to create two thread which output interleave like below
Thread1:1=>Ping!
Thread2:2=>Pong!
Thread1:3=>Ping!
Thread1:4=>Ping!
Thread2:5=>Pong!
Thread2:6=>Pong!
Thread1:7=>Ping!
Thread2:8=>Pong!
Thread1:9=>Ping!
..........
until 50
and my code is below
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
void* increment1(void* arg);
void* increment2(void* arg);
int count = 0;
sem_t sem;
int main() {
//variable initialize
pthread_t thread1, thread2;
int res1 = 0, res2 = 0;
int number = 0;
int i = 0;
//create semaphore
if (sem_init(&sem, 0, 1) == -1){
printf("Semaphore creation failed!!\n");
exit(EXIT_FAILURE);
}
for (i = 0; i < 25; ++i){
//create thread
res1 = pthread_create(&thread1, NULL, increment1, NULL);
if (res1 != 0) {
printf("Thread1 creation failed!!\n");
exit(EXIT_FAILURE);
}
//wait thread synchronization
pthread_join( thread1, NULL);
res2 = pthread_create(&thread2, NULL, increment2, NULL);
if (res2 != 0) {
printf("Thread2 creation failed!!\n");
exit(EXIT_FAILURE);
}
//wait thread synchronization
pthread_join( thread2, NULL);
}
exit(EXIT_SUCCESS);
}
void* increment1(void* arg) {
sem_wait(&sem);
count ++;
printf("Thread1:%d\nPing!\n",count);
fsync(fileno(stdout));
sem_post(&sem);
}
void* increment2(void* arg) {
sem_wait(&sem);
count ++;
printf("Thread2:%d\nPong!\n",count);
fsync(fileno(stdout));
sem_post(&sem);
}
But I think that what I do isn't using two thread in parallel and is wrong, what I use is sequential alternative executing two thread and it isn't not in parallel.(By using pthread_join, thread2 will execute after thread1 finish).
I try to using semaphore it seem that it cannot assure the thread execution order.
What I want to ask is
1.how to using semaphore to assure the two thread order?
2.how to pause the thread and resume it? I think that I do is create new two pthread in a loop cycle.
Thank in advance.
Add a second semaphore and initialize it to zero so that thread1 is forced to first. Then increment1 and increment2 keep signally that it is the other threads turn to go. You had some minor hangups with where joined things that you can figure out.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
void* increment1(void* arg);
void* increment2(void* arg);
int count = 0;
sem_t sem1, sem2;
int main()
{
pthread_t thread[2];
int res = 0;
int number = 0;
int i = 0;
if (sem_init(&sem1, 0, 1) == -1)
{
printf("Semaphore creation failed!!\n");
exit(EXIT_FAILURE);
}
if (sem_init(&sem2, 0, 0) == -1)
{
printf("Semaphore creation failed!!\n");
exit(EXIT_FAILURE);
}
for (i = 0; i < 25; ++i)
{
res = pthread_create(&thread[0], NULL, increment1, NULL);
if (res != 0)
{
printf("Thread creation failed!!\n");
exit(EXIT_FAILURE);
}
res = pthread_create(&thread[1], NULL, increment2, NULL);
if (res != 0)
{
printf("Thread creation failed!!\n");
exit(EXIT_FAILURE);
}
for (int j = 0; j < 2; ++j)
{
pthread_join(thread[j], NULL);
}
}
exit(EXIT_SUCCESS);
}
void* increment1(void* arg)
{
sem_wait(&sem1);
count ++;
printf("Thread1:%d Ping!\n", count);
fsync(fileno(stdout));
sem_post(&sem2);
}
void* increment2(void* arg)
{
sem_wait(&sem2);
count ++;
printf("Thread2:%d Pong!\n", count);
fsync(fileno(stdout));
sem_post(&sem1);
}
Thank for you guys, I have modified it and it seems fine.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
int count = 0;
void* increment_1(void* arg);
void* increment_2(void* arg);
sem_t sem_1, sem_2;
sem_t c_sem;
int main() {
//variable initialize
pthread_t thread1, thread2;
int res1 = 0, res2 = 0;
int number = 0;
int i = 0;
//create semaphore
if (sem_init(&c_sem, 0, 1) == -1){
printf("Semaphore creation failed!!\n");
exit(EXIT_FAILURE);
}
if (sem_init(&sem_1, 0, 1) == -1){
printf("Semaphore creation failed!!\n");
exit(EXIT_FAILURE);
}
if (sem_init(&sem_2, 0, 0) == -1){
printf("Semaphore creation failed!!\n");
exit(EXIT_FAILURE);
}
//create thread
res1 = pthread_create(&thread1, NULL, increment_1, NULL);
if (res1 != 0) {
printf("Thread1 creation failed!!\n");
exit(EXIT_FAILURE);
}
res2 = pthread_create(&thread2, NULL, increment_2, NULL);
if (res2 != 0) {
printf("Thread2 creation failed!!\n");
exit(EXIT_FAILURE);
}
//wait thread synchronization
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
exit(EXIT_SUCCESS);
}
void* increment_1(void* arg) {
while(1){
sem_wait(&sem_1);
sem_wait(&c_sem);
if(count == 50){
sem_post(&c_sem);
sem_post(&sem_2);
exit(EXIT_SUCCESS);
}
count ++;
printf("Thread1:%d->Ping!\n",count);
fsync(fileno(stdout));
sem_post(&c_sem);
sem_post(&sem_2);
}
}
void* increment_2(void* arg) {
while(1){
sem_wait(&sem_2);
sem_wait(&c_sem);
if(count == 50){
sem_post(&c_sem);
sem_post(&sem_1);
exit(EXIT_SUCCESS);
}
count ++;
printf("Thread2:%d->Pong!\n",count);
fsync(fileno(stdout));
sem_post(&c_sem);
sem_post(&sem_1);
}
}
I want to create a number of threads specified by the user. The code I have written for this is:
int nhijos = atoi(argv[1]);
thread = malloc(sizeof(pthread_t)*nhijos);
for (i = 0; i < nhijos; i++){
if (pthread_create ( &thread[i], NULL, &hilos_hijos, (void*) &info ) != 0){
perror("Error al crear el hilo. \n");
exit(EXIT_FAILURE);
}
Is this correct?
Yes, but I would do the following:
validate that argc > 1 before calling atoi(argv[1])
validate numberOfThreads is a positive number and less than a reasonable range. (In case the user types 1000000).
validate the return value from malloc is not null.
pthread_create will not set errno on failure. So perror may not be the right function to call on failure.
...
if (argc > 1)
{
int numberOfThreads = atoi(argv[1]);
if ((numberOfThreads <= 0) || (numberOfThreads > REASONABLE_THREAD_MAX))
{
printf("invalid argument for thread count\n");
exit(EXIT_FAILURE);
}
thread = malloc(sizeof(pthread_t)*numberOfThreads);
if (thread == NULL)
{
printf("out of memory\n");
exit(EXIT_FAILURE);
}
for (i = 0; i < numberOfThreads; i++)
{
if (pthread_create ( &thread[i], NULL, &hilos_hijos, (void*) &info ) != 0)
{
printf("Error al crear el hilo. \n");
exit(EXIT_FAILURE);
}
}
#include<stdio.h>
#include<pthread.h>
void* thread_function(void)
{
printf("hello");
}
int main(int argc,char *argv[])
{
int noOfThread= atoi(argv[1]);
pthread_t thread_id[noOfThread];
int i;
int status;
for(i=0;i<noOfThread;i++)
{
pthread_create (&thread_id[i], NULL , &thread_function, NULL);
}
for(i=0;i<noOfThread;i++)
pthread_join(thread_id[i],NULL);
}
Now compile thi and run as
./a.exe 3
So 3 thread will be created
In your code
1> why you are going to malloc ?
2> If malloc then why you are not going to free that ?