created thread doesn't get executed - linux

here I come again with a new question for this (blasted) threads programming.
Here is my code, hope you can help me understand what's wrong with it (keep in mind I had to write this code again, not copy-paste, so there may be some type errors - the compiled code is ok and works, so the problem is not the syntax).
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int i=0;
void *TFun(void *TArg)
{
printf("THREAD i=%d\n", i);
i++;
return NULL;
}
int main()
{
pthread_t TID;
TID=pthread_create(&TID, NULL, TFun, NULL);
pthread_join(TID, NULL);
printf("THREAD i=%d\n", i);
i++;
exit(0);
}
I expect this to print "THREAD i=0" and then "MAIN i=1", but this doesn't happen. it only prints "MAIN i=0", the Thread is not executed.
https://i.ibb.co/Y0KYWCK/code.png
https://i.ibb.co/pznZ3TT/result.png

The value of TID is normally written by reference within pthread_create(), but was also being overwritten with the int return value; change to an added int variable:
(old)
TID=pthread_create(&TID, NULL, TFun, NULL);
(new)
int pcr;
pcr = pthread_create(&TID, NULL, TFun, NULL);

Related

Pause thread execution without using condition variable or other various synchronization pritmives

Problem
I wish to be able to pause the execution of a thread from a different thread. Note the thread paused should not have to cooperate. The pausing of the target thread does not have to occur as soon as the pauser thread wants to pause. Delaying the pausing is allowed.
I cannot seem to find any information on this, as all searches yielded me results that use condition variables...
Ideas
use the scheduler and kernel syscalls to stop the thread from being scheduled again
use debugger syscalls to stop the target thread
OS-agnostic is preferable, but not a requirement. This likely will be very OS-dependent, as messing with scheduling and threads is a pretty low-level operation.
On a Unix-like OS, there's pthread_kill() which delivers a signal to a specified thread. You can arrange for that signal to have a handler which waits until told in some manner to resume.
Here's a simple example, where the "pause" just sleeps for a fixed time before resuming. Try on godbolt.
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
void safe_print(const char *s) {
int saved_errno = errno;
if (write(1, s, strlen(s)) < 0) {
exit(1);
}
errno = saved_errno;
}
void sleep_msec(int msec) {
struct timespec t = {
.tv_sec = msec / 1000,
.tv_nsec = (msec % 1000) * 1000 * 1000
};
nanosleep(&t, NULL);
}
void *work(void *unused) {
(void) unused;
for (;;) {
safe_print("I am running!\n");
sleep_msec(100);
}
return NULL;
}
void handler(int sig) {
(void) sig;
safe_print("I am stopped.\n");
sleep_msec(500);
}
int main(void) {
pthread_t thr;
pthread_create(&thr, NULL, work, NULL);
sigset_t empty;
sigemptyset(&empty);
struct sigaction sa = {
.sa_handler = handler,
.sa_flags = 0,
};
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1, &sa, NULL);
for (int i = 0; i < 5; i++) {
sleep_msec(1000);
pthread_kill(thr, SIGUSR1);
}
pthread_cancel(thr);
pthread_join(thr, NULL);
return 0;
}

Shared Memory Fork Process Learning in Linux

Good day to all! I am just trying to learn more about parent and child processes in Linux using the fork () function.
I am trying to make a very simple program where after setting up the shared memory segment, i can get a result from a child and output it in the parent .
My problem is it does not seem to work. Here is what i have so far
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/types.h>
#define SZ 20
typedef struct
{
int size;
int cz[SZ];
}shared_data;
shared_data* Collatz(int);
int main (void)
{
pid_t pid;
int seg_id,size=sizeof(shared_data);
seg_id=shmget(IPC_PRIVATE,size,S_IRUSR | S_IWUSR);
shared_data *sd=(shared_data *)shmat(seg_id,NULL, 0);
int usr=-1,count,i;
while(usr<1 ||usr >9)
{
printf("Please Enter a Number between 1-9:");
scanf("%d",&usr);
}
pid=fork();
if(pid<0)
{
printf("Fork Failed");
return 1;
}
if(pid==0)
{
sd=Collatz(usr);
shmdt(sd);
}
else
{
wait(NULL);
printf("\nThe Sequence is: %d ",count);
for(i=0;i<sd->size;i++)
{
printf(" %d ",sd->cz[i]);
}
printf("\n");
}
return 0;
}
shared_data* Collatz(int val)
{
int i=0;
shared_data *data=malloc(sizeof(shared_data));
data->cz[i]=val;
while(val!=1)
{
i++;
if(val%2==0)
val=val/2;
else
val=(3*val)+1;
data->cz[i]=val;
}
data->size=i;
return data;
}
You are assigning to the memory allocated with malloc, not the memory allocated with shmget/shmat. I'm not 100% sure what you intended, but it may be that simply changing the assignment in the child to the following would do the trick. (This will overlay the shared memory with the mallocd content that you initialized in Collatz().)
*sd=Collatz(usr);
[Edit: I should add that your current code sd=Collatz(usr) is instead overwriting the pointer value you got back from the shmat() call rather than the pointed-to memory area.]

Can some one please explain the following code of threads?

So I am new to system programming and learning threads.What does the term posix means? I need help in understanding the following code.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *print_message_function( void *ptr );
main()
{
pthread_t thread1, thread2;
const char *message1 = "Thread 1";
const char *message2 = "Thread 2";
int iret1, iret2;
iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
printf("Thread 1 returns: %d\n",iret1);
printf("Thread 2 returns: %d\n",iret2);
exit(0);
}
void *print_message_function( void *ptr )
{
char *message;
message = (char *) ptr;
printf("%s \n", message);
}
I dont understand the line: pthread_join( thread1, NULL);
and the function: void *print_message_function( void *ptr ).
Also, what does the variable iret returns?
It spawns two threads.
Saves their "return values" to variables previously declared.
Joins to threads, basically waits for them to stop.
Prints the variables
exits with status 0, normal successful exit
posix is a general standard for Unix like operating systems. E.g file structure etc
You should read posix documentation.
I dont understand the line: pthread_join( thread1, NULL); and the
function: void *print_message_function( void *ptr ).
pthread_join blocks until the thread terminates
void *print_message_function( void *ptr ) is a function returning void* and receiving a void* as parameter
Again, you should read posix documentation (and learn more C).

how to show which thread is being rejected to Enter in critical section by use of semaphore

This Code is pretty fine to demonstrate Critical Section problem, but i've TWO QUERIES about the code,
How to show WHICH THREAD is being rejected to Enter in Critical Section ?
thread 'A', 'B', 'C' are created in listed order. HOW can i start them at single time ?
Here is the code:
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
void *doSomething1();
void *doSomething2();
void *doSomething3();
sem_t sem;
int main() {
// initialize semaphore to 2
sem_init(&sem, 1, 2);
pthread_t thread1, thread2, thread3;
pthread_create(&thread1, NULL, &doSomething1, NULL);
pthread_create(&thread2, NULL, &doSomething2, NULL);
pthread_create(&thread3, NULL, &doSomething3, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
return 0;
}
void doSomething(char c) {
int i, time;
for (i = 0; i < 3; i++) {
if (sem_wait(&sem) == 0) {
// generate random amount of time (< 7 seconds)
time = (int) ((double) rand() / RAND_MAX * 7 );
printf("#thread %c GOT-ACCESS to CRITICAL SESSION for %d sec\n", c, time);
sleep(time);
printf("\t->thread %c RELEASED CRITICAL SESSION\n",c);
sem_post(&sem);
}
else
printf("thread %c FAILED TO ENTER CRITICAL SECTION",c);
}
}
void *doSomething1() {
// thread A
doSomething('A'); return 0;
}
void *doSomething2() {
// thread B
doSomething('B'); return 0;
}
void *doSomething3() {
// thread C
doSomething('C'); return 0;
}
In order for a thread to be "rejected" from entering you would have to replace sem_wait(), which is a blocking call with sem_trywait()or sem_timedwait()although then they might not ever enter the critical section (without some more modifications to the code). But since you only want to see when a thread is denied entering the section this should be sufficient. (for more information on these methods visit the man page http://linux.die.net/man/3/sem_wait ).
As for the second the question the answer is that you actually cannot start all threads at once, they have to start in some sort of order. However you can (if you want) start multiple threads and use a semaphore to block them until all threads are ready and then release them all at once, which is as close as you can get to starting them at once.

Differences between POSIX threads on OSX and LINUX?

Can anyone shed light on the reason that when the below code is compiled and run on OSX the 'bartender' thread skips through the sem_wait() in what seems like a random manner and yet when compiled and run on a Linux machine the sem_wait() holds the thread until the relative call to sem_post() is made, as would be expected?
I am currently learning not only POSIX threads but concurrency as a whole so absoutely any comments, tips and insights are warmly welcomed...
Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
//using namespace std;
#define NSTUDENTS 30
#define MAX_SERVINGS 100
void* student(void* ptr);
void get_serving(int id);
void drink_and_think();
void* bartender(void* ptr);
void refill_barrel();
// This shared variable gives the number of servings currently in the barrel
int servings = 10;
// Define here your semaphores and any other shared data
sem_t *mutex_stu;
sem_t *mutex_bar;
int main() {
static const char *semname1 = "Semaphore1";
static const char *semname2 = "Semaphore2";
pthread_t tid;
mutex_stu = sem_open(semname1, O_CREAT, 0777, 0);
if (mutex_stu == SEM_FAILED)
{
fprintf(stderr, "%s\n", "ERROR creating semaphore semname1");
exit(EXIT_FAILURE);
}
mutex_bar = sem_open(semname2, O_CREAT, 0777, 1);
if (mutex_bar == SEM_FAILED)
{
fprintf(stderr, "%s\n", "ERROR creating semaphore semname2");
exit(EXIT_FAILURE);
}
pthread_create(&tid, NULL, bartender, &tid);
for(int i=0; i < NSTUDENTS; ++i) {
pthread_create(&tid, NULL, student, &tid);
}
pthread_join(tid, NULL);
sem_unlink(semname1);
sem_unlink(semname2);
printf("Exiting the program...\n");
}
//Called by a student process. Do not modify this.
void drink_and_think() {
// Sleep time in milliseconds
int st = rand() % 10;
sleep(st);
}
// Called by a student process. Do not modify this.
void get_serving(int id) {
if (servings > 0) {
servings -= 1;
} else {
servings = 0;
}
printf("ID %d got a serving. %d left\n", id, servings);
}
// Called by the bartender process.
void refill_barrel()
{
servings = 1 + rand() % 10;
printf("Barrel refilled up to -> %d\n", servings);
}
//-- Implement a synchronized version of the student
void* student(void* ptr) {
int id = *(int*)ptr;
printf("Started student %d\n", id);
while(1) {
sem_wait(mutex_stu);
if(servings > 0) {
get_serving(id);
} else {
sem_post(mutex_bar);
continue;
}
sem_post(mutex_stu);
drink_and_think();
}
return NULL;
}
//-- Implement a synchronized version of the bartender
void* bartender(void* ptr) {
int id = *(int*)ptr;
printf("Started bartender %d\n", id);
//sleep(5);
while(1) {
sem_wait(mutex_bar);
if(servings <= 0) {
refill_barrel();
} else {
printf("Bar skipped sem_wait()!\n");
}
sem_post(mutex_stu);
}
return NULL;
}
The first time you run the program, you're creating named semaphores with initial values, but since your threads never exit (they're infinite loops), you never get to the sem_unlink calls to delete those semaphores. If you kill the program (with ctrl-C or any other way), the semaphores will still exist in whatever state they are in. So if you run the program again, the sem_open calls will succeed (because you don't use O_EXCL), but they won't reset the semaphore value or state, so they might be in some odd state.
So you should make sure to call sem_unlink when the program STARTS, before calling sem_open. Better yet, don't use named semaphores at all -- use sem_init to initialize a couple of unnamed semaphores instead.

Resources