Rand() function in threads - multithreading

#include <pthread.h>
#ifndef __linux__
#include <windows.h>// to include the windows.h library//
#endif
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
#include <sys/timeb.h>
void *PrintHello(void *threadid)
{
srand(time(NULL));
long tid,a;
tid = (long)threadid;
a=rand()%5;
printf("Hello World! It's me, thread #%ld!%ld\n", tid,a);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t,a;
srand(time(NULL));
for(t=0; t<NUM_THREADS; t++){
a=rand()%5;
printf("In main: creating thread %ld,%ld\n", t,a);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
Alright I have this simple code and when I compile it inside the main() the random numbers
are different from one another but when i try to generate random numbers inside the threads, all the numbers that are produced are the same.

Try seeding from outside the threads. The problem is that you get the same seed for each thread

Related

What happens without a binary semaphore

Assume the code below demonstrating a binary semaphore example.
In this example, we have a pthread that reads the source.txt and attempts to copy the content to destination.txt while locking it using a binary semaphore.
What happens in the comment section below without the semaphore?
#include <cstdlib>
#include <memory>
#include <filesystem>
#define _TIMESPEC_DEFINED
#include <pthread.h>
#include <semaphore.h>
#include <thread>
#include <valarray>
pthread_t StartFileAccessThread();
void *CopyFile(void *parameters);
int main(int argc, char* argv[])
{
pthread_t thread = StartFileAccessThread();
void *returnValue;
pthread_join(thread, &returnValue);
getchar();
return EXIT_SUCCESS;
}
pthread_t StartFileAccessThread()
{
std::string sourcePath("source.txt");
std::string destinationPath("dest.txt");
sem_t semaphore;
sem_init(&semaphore, 0, 0);
pthread_t thread;
void *parameters[3];
parameters[0] = &semaphore;
parameters[1] = &sourcePath;
parameters[2] = &destinationPath;
pthread_create(&thread, nullptr, &CopyFile, parameters);
// What happens without the binary semaphore?
sem_wait(&semaphore);
sem_destroy(&semaphore);
printf("Freeing ressources.\n");
return thread;
}
void *CopyFile(void *rawParameter)
{
void **parameters = static_cast<void **>(rawParameter);
sem_t *semaphore = static_cast<sem_t *>(parameters[0]);
std::string sourcePath(*static_cast<std::string *>(parameters[1]));
std::string destinationPath(*static_cast<std::string *>(parameters[2]));
sem_post(semaphore);
std::this_thread::sleep_for(std::chrono::seconds(2));
copy_file(sourcePath, destinationPath, std::experimental::filesystem::copy_options::overwrite_existing);
printf("File copied \n");
return nullptr;
}
What happens in the comment section below without the semaphore?
Without the semaphore, function startFileAccessThread() may return before the new thread finishes (or starts) copying its parameters from the argument object. That object is local to startFileAccessThread(), so its lifetime ends when that function returns. Undefined behavior results if the copy thread's accesses to it do not happen before that.

how can I configure the context switch time slice in Linux?

I have following code.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void* a(void* ptr) {
while(1){
printf("1");
printf("2");
printf("3");
printf("4");
}
}
int main(int argc, char** argv) {
pthread_t t;
pthread_create(&t, NULL, a, 0);
while(1){
printf("a");
printf("b");
printf("c");
printf("d");
}
pthread_join(t, NULL);
return 0;
}
the result of this code is "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd1234123412341234..........."
but I want them to be mixed like "ab12c3d4a1bcda23b......"
how can I configure the scheduling time slice of a thread?
is this possible?
thank you in advance
You can modify scheduling behaviour by setting the sched param (pthread_setschedparam(3)) to for example SCHED_RR (RR means Round Robin). There is SCHED_FIFO, SCHED_RR and SCHED_OTHER with SCHED_OTHER being the default.

How to read the valgrind return value from child processes?

i am running valgrind in a bash script to use it for automated testing. I already added the option to return an exit code on error and to trace children.
/usr/bin/valgrind --error-exitcode=1 --trace-children=yes ./test_prog
My programm forks other processes and I can see the output of valgrind running the different processes in the terminal. The problem is, that the exit code option only seems to work when there is an error in the parent process. Because even though there is an error (SIGSEGV) in one of the child processes the exit code of valgrind is still 0, which means it is useless for the automated testing of several processes.
So is there any option, that would make the parent valgrind catch the error in the child and return it? I already looked into the man page. Maybe there would be another solution to this problem, like grepping the output of the children to the terminal for any error messages?
Thanks in advance.
it's important to implement a proper error handling in the code. Compare following two pieces of code.
A:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <signal.h>
#define BUFSIZE 1024
int incr=0;
int loop=1;
void runTicks(const char *n) {
time_t t;
char buf[BUFSIZE+1];
pid_t pid;
int counter;
pid=getpid();
counter=0;
while(loop) {
sleep(1);
t=time(NULL);
strftime(buf,BUFSIZE,"%Y.%m.%d %H:%M:%S",localtime(&t));
printf("%s[%d] %s\n",n,pid,buf);
counter+=incr;
if(counter>5) memcpy((void *)1,buf,1); /* this line is for causing SEGV */
}
}
void handler(int s) {
if(s==SIGCHLD) {
printf("Received SIGCHLD\n");
loop=0;
}
}
void setHandler() {
struct sigaction sa;
sa.sa_handler=handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags=SA_NOCLDSTOP;
if(sigaction(SIGCHLD,&sa,NULL)!=0) {
printf("Cannot set signal handler, there is no purpose in running the test\n");
exit(0);
}
}
int main() {
pid_t pid;
printf("start\n");
pid=fork();
if(pid==-1) {
printf("fork failed\n");
exit(10);
}
if(pid==0) {
printf("child\n");
incr=1;
usleep(500000);
runTicks("C");
exit(1);
} else {
printf("parent spawned child pid=%d\n",pid);
setHandler();
runTicks("P");
exit(0);
}
}
B:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
#define BUFSIZE 1024
int incr=0;
int loop=1;
void runTicks(const char *n) {
time_t t;
char buf[BUFSIZE+1];
pid_t pid;
int counter;
pid=getpid();
counter=0;
while(loop) {
sleep(1);
t=time(NULL);
strftime(buf,BUFSIZE,"%Y.%m.%d %H:%M:%S",localtime(&t));
printf("%s[%d] %s\n",n,pid,buf);
counter+=incr;
if(counter>5) memcpy((void *)1,buf,1); /* this line is for causing SEGV */
}
}
void handler(int s) {
if(s==SIGCHLD) {
int status;
printf("Received SIGCHLD\n");
wait(&status);
printf("Exit code from child: %d\n",status);
if(status!=0) exit(status);
loop=0;
}
}
void setHandler() {
struct sigaction sa;
sa.sa_handler=handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags=SA_NOCLDSTOP;
if(sigaction(SIGCHLD,&sa,NULL)!=0) {
printf("Cannot set signal handler, there is no purpose in running the test\n");
exit(0);
}
}
int main() {
pid_t pid;
printf("start\n");
pid=fork();
if(pid==-1) {
printf("fork failed\n");
exit(10);
}
if(pid==0) {
printf("child\n");
incr=1;
usleep(500000);
runTicks("C");
exit(1);
} else {
printf("parent spawned child pid=%d\n",pid);
setHandler();
runTicks("P");
exit(0);
}
}
Run those first without valgrind and compare the exit code of both programs. Then run them under valgrind and enjoy.
Using such construction you even don't need to run it under valgrind, to catch segfaults from child processes.

segfault during freeing memory in a linked-list(queue) by a thread

I have created a thread. The main function is creating an element and appending it to the Tail/End of a queue. The thread is reading the list from Head/Start and is releasing the memory after.
I have the following code:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void *print_message_function( void *ptr );
typedef struct stCheckFree
{
char name[30];
int doneflag;
struct stCheckFree *next;
}CheckFree;
CheckFree *gHead=NULL;
CheckFree *gTail=NULL;
int main()
{
pthread_t thread1;
char *message1 = "Thread 1";
int iret1;
unsigned long TestCount=1;
CheckFree *pCurr=NULL;
CheckFree *pTemp=NULL;
iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
while(1)
{
pCurr=malloc(sizeof(CheckFree));
memset(pCurr,0,sizeof(CheckFree));
printf("Malloc\n");
sprintf(pCurr->name,"Test-%ld",TestCount); TestCount++;
pCurr->doneflag=0;
pCurr->next=NULL;
pTemp=gTail;
gTail=pCurr;
if(pTemp) pTemp->next=gTail;
if(!gHead)
{
gHead=gTail;
}
}
return 0;
}
void *print_message_function( void *ptr )
{
CheckFree *pTrav;
while(1)
{
pTrav=gHead;
if(pTrav)
{
printf("[%s]\n",pTrav->name);
pTrav->doneflag=1;
gHead=gHead->next;
free(pTrav);
}
}
}
When I run the code its giving me a segfault. What might be the issue?
Please help!
Thanks.
PS- If i remove the free(), its running splendidly!!!
-----------------------------------------------------------------------------------
---EDIT 1---
-----------------------------------------------------------------------------------
I am not sure if this is the fix, but I need more inputs from other stackoverflow members.
void *print_message_function( void *ptr )
{
CheckFree *pTrav;
while(1)
{
pTrav=gHead;
if(pTrav)
{
printf("[%s]\n",pTrav->name);
pTrav->doneflag=1;
gHead=gHead->next;
if(!gHead) gTail=NULL; /* NEW CODE */
free(pTrav);
sleep(0.7);
}
}
}
Please help as it is important! :)
Thanks again.
-----------------------------------------------------------------------------------
---EDIT 2---
-----------------------------------------------------------------------------------
The code change:-
if(!gHead) gTail=NULL; /* NEW CODE */
is destroying data by re-initializing NULL over it.
You can see it by just doing the following code changes:
...pTemp=gTail;
gTail=pCurr;
if(pTemp) pTemp->next=gTail;
if(!gTail)printf("Data lost\n");
if(!gHead)
{...
Please help me to rectify this issue...
-----------------------------------------------------------------------------------
---EDIT 3---
-----------------------------------------------------------------------------------
Following #wazy's recommendation of using mutex lock I updated the code as follows:-
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void * thread_function( void *ptr );
typedef struct stCheckFree
{
char name[30];
int doneflag;
struct stCheckFree *next;
}CheckFree;
pthread_mutex_t lock; // EDIT 3
CheckFree *gHead=NULL;
CheckFree *gTail=NULL;
int main()
{
pthread_t thread1;
char *message1 = "Thread 1";
int iret1;
unsigned long TestCount=1;
CheckFree *pCurr=NULL;
CheckFree *pTemp=NULL;
if (pthread_mutex_init(&lock, NULL) != 0) // EDIT 3
{
printf("\n mutex init failed\n");
return 1;
}
iret1 = pthread_create( &thread1, NULL, thread_function, (void*) message1);
while(1)
{
pCurr=malloc(sizeof(CheckFree));
memset(pCurr,0,sizeof(CheckFree));
sprintf(pCurr->name,"Test-%ld",TestCount); TestCount++;
pCurr->doneflag=0;
pCurr->next=NULL;
pTemp=gTail;
gTail=pCurr;
if(pTemp) pTemp->next=gTail;
//pthread_mutex_lock(&lock); // EDIT 3(commented out)
if(!gHead)
{
pthread_mutex_lock(&lock); // EDIT 4
gHead=gTail;
pthread_mutex_unlock(&lock); // EDIT 4
}
//pthread_mutex_unlock(&lock); // EDIT 3(commented out)
}
pthread_join( thread1, NULL);
printf("Thread 1 returns: %d\n",iret1);
return 0;
}
void * thread_function( void *ptr )
{
CheckFree *pTrav;
while(1)
{
pTrav=gHead;
if(pTrav)
{
//printf("[%s]\n",pTrav->name);
pTrav->doneflag=1;
gHead=gHead->next;
if(!gHead) sleep(1);//gTail=NULL;
free(pTrav);
}
}
}
Am I on the right track?????
Thanks!!!
Running your code gives me double free or corruption (fasttop) from glibc. Looking at your code I see that you are using both gHead in your thread1 and in your main thread. It seems to be a multithreading synchronization problem.

Arguments were passed wrong in pthread

I write a code to print out strings: "Thread 0" to "Thread 4" using pthread.
Here is my code:
Case 1:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *print_message_function(void* parameter) {
long *i = (long *)parameter;
printf("Thread %ld\n", *i);
pthread_exit(0);
}
int main(int argc, char *argv[]) {
pthread_t threads[5];
long i = 0;
for (i = 0; i < 5; i++) {
pthread_create(&threads[i], 0, print_message_function, (void *)&i);
}
pthread_exit(NULL);
}
But the result is:
Thread 2
Thread 3
Thread 3
Thread 4
Thread 5
or:
Thread 0
Thread 0
Thread 0
Thread 0
Thread 0
It changed when I run it again. So I don't know why the values I passed are (2 to 5) or all (0) or ..... (many cases). I think my arguments I passed is from 0 to 4.
Case 2:
When I change to the new code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *print_message_function(void *parameter);
int main(int argc, char *argv[]) {
pthread_t threads[5];
int i = 0;
for (i = 0; i < 5; i++) {
char *msg = (char*)malloc(sizeof(char));
sprintf(msg, "Thread %d", i);
pthread_create(&threads[i], 0, print_message_function, (void *)msg);
}
}
void *print_message_function(void *parameter) {
printf("%s\n", (char *)parameter);
}
The result is:
Thread 1
Thread 0
Thread 3
Thread 2
Thread 4
Thread 4
It means the loop run 6 times! Why?
Change Case 1 to this:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *print_message_function(void* parameter) {
long i = (long)parameter; // <<<
printf("Thread %ld\n", i); // <<<
pthread_exit(0);
}
int main(int argc, char *argv[]) {
pthread_t threads[5];
long i = 0;
for (i = 0; i < 5; i++) {
pthread_create(&threads[i], 0, print_message_function, (void *)i); // <<<
}
pthread_exit(NULL);
}
The reason that you were seeing inconsistent results before was because you were passing a pointer to each thread where each pointer was pointing at the same local variable, which you were then modifying.
In Case 2 you are mallocing only a single char and then trying to write a string to it. It should be fairly easy to fix.
Your case 2 approach is valid, however you need to fix the malloc part to allocate enough bytes. Change it to
char *msg = (char*)malloc(sizeof(char) * (strlen("Thread ") + 10));
// assuming i will take at most 9-digits (unlikely case)
For your case 1, you are passing address of i. But the value of i is changing thread function will get whatever value is there at that location when it tries to print. Also note that address of i may not be valid by the time thread function executes as its allocated on stack and will go away when main function returns.

Resources