I have started working on POSIX threads. I wrote a simple code.
My question is on Mutex.
Initializing the mutex inside threaded function gives wrong result. While initializing the mutex inside main function (before creation of threads) gives proper result. Why is that happening?
The count value is expected to be 200000 but it is showing some improper value < 200000.
Here is my code.
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <malloc.h>
void *thread_handler (void *name);
unsigned long int count=0;
pthread_mutex_t lock;
void main () {
pthread_t thread_num[2];
pthread_attr_t attr;
pthread_attr_init (&attr);
int i;
for (i=0;i<2;i++) {
if (pthread_create (&thread_num[i],&attr,(void *) thread_handler,NULL)<0) {
printf ("\n Error in Creating the Threads");
}
}
for (i=0;i<2;i++) {
pthread_join(thread_num[i],NULL); //Waiting for the Thread to Exit
}
printf ("\n The value of count=%ld\n",count);
}
void *thread_handler (void *arg) {
int i;
if (pthread_mutex_init (&lock,NULL)!=0) {
printf ("\n Error in Initializing the Mutex");
}
pthread_mutex_lock (&lock);
for (i=0;i<100000;i++) {
count++;
}
pthread_mutex_unlock(&lock);
pthread_exit(NULL);
}
Thanks in Advance,
NDPrasad.
When you initialize the mutex inside the thread_handler function, it is initialized twice(because you create two threads that execute this function). It causes undefined behavior(which means that anything can happen).
A quote from here:
Attempting to initialize an already initialized mutex results in undefined behavior.
Related
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;
}
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.]
My code is as follows,The first time ,alarm works very well and handler2() function can work. however, the alarm doesn't work after it implement "doMain()" in the "handler2()".
I mean after the second time print ""In main Pleasae input: \n"", handler2() doesn't wrok anymore.
I don't know why? My code as follows:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
#define MAX_LEN_COMM 64
jmp_buf jumper;
int stop =0; //o is not stop ,otherwise is stop;
void hanlder2();
void doMain();
void handler2()
{
int len_command = 0;
char character;
char commandStr[60];
printf("******************************\n");
printf("In Alarm Pleasae input: \n");
while((character=getchar())!='\n')
{
commandStr[len_command]=character;
len_command++;
}
commandStr[len_command]='\0';
printf("In Alarm input is %s\n",commandStr);
if (strcmp(commandStr,"N")==0||strcmp(commandStr,"n")==0){
printf("In Alarm You put no, we will stop alarm \n");
stop=1;
longjmp(jumper, 2);
}
else if(strcmp(commandStr,"Y")==0||strcmp(commandStr,"y")==0){
printf("In Alarm You put yes, we will continue alarm \n");
signal(SIGALRM, handler2);
alarm(5);
doMain();
}
}
void doMain(){
while(1){
setjmp(jumper);
if(stop==0){
signal(SIGALRM, handler2);
printf("return time %d\n",alarm(5));
}
int len_command = 0;
char character;
char commandStr[60];
printf("In main Pleasae input: \n");
while((character=getchar())!='\n')
{
commandStr[len_command]=character;
len_command++;
}
commandStr[len_command]='\0';
printf("In main input is %s\n",commandStr);
if (strcmp(commandStr,"N")==0||strcmp(commandStr,"n")==0){
printf("In main You put no\n");
}
else if(strcmp(commandStr,"Y")==0||strcmp(commandStr,"y")==0){
printf("In main You put yes\n");
}
}
}
void main()
{
doMain();
}
What you are doing is very wrong.
First, the signature of the handler should be void handler(int sig).
Second, there are very few functions that are safe to use within a handler so you should try to get out of a handler as quickly as possible and definitely not doing console i/o. You are using several unsafe library functions.
Lastly a signal handler is a function. It runs and returns to where your program was interrupted by the signal. During the time a handler runs signals of the same type are not deliverd. By calling doMain() from the handler - which is crazy - the handler never ends. Because it doesn't end you won't see any more alarm signals.
I just wrote the following code to understand better how Threads work:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int globalVariable = 1;
void *myfunc (void *myvar);
int main (void) {
pthread_t thread1;
int waitms;
while(globalVariable <= 50){
printf("Main function: %d \n", globalVariable);
if (globalVariable==9) {
pthread_create(&thread1, NULL, myfunc, NULL);
pthread_join(thread1, NULL);
}
usleep(300000);
globalVariable++;
}
return 0;
}
void *myfunc (void *myvar){
int waitms;
while(globalVariable<=50) {
printf("Thread1: %d \n", globalVariable);
usleep(300000);
globalVariable++;
}
return 0;
}
The code must print a value of a global variable that is incremented in the main function. When this variable has the value 9, the main function calls a thread, that does the same as the original main function, but without calling another thread.
In the Output I get the first 9 prints of the main function and all the following ones are from the thread. Shouldn't they be mixed? What have I done wrong?
No because you are joining the thread1, so the main thread blocks until thread1 dies. Once thread1 dies it resumes but thread1 has incremented the globalVariable to a point where the main thread exits the first while loop.
Removing the join you will see mixed results, better still would be to move the join outside of the while loop so if thread1 is still alive when the main thread exits the loop it waits... it's most likely going to dead by that time but you should make sure your child threads have finished up before exiting the main thread.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
void *thread_function(void *arg);
sem_t bin_sem;
#define WORK_SIZE 1024
char work_area[WORK_SIZE];
int main() {
int res;
pthread_t a_thread;
void *thread_result;
res = sem_init(&bin_sem, 0, 0);
if (res != 0) {
perror(“Semaphore initialization failed”);
exit(EXIT_FAILURE);
}
res = pthread_create(&a_thread, NULL, thread_function, NULL);
if (res != 0) {
perror(“Thread creation failed”);
exit(EXIT_FAILURE);
}
printf(“Input some text. Enter ‘end’ to finish\n”);
while(strncmp(“end”, work_area, 3) != 0) {
fgets(work_area, WORK_SIZE, stdin);
sem_post(&bin_sem);
}
printf(“\nWaiting for thread to finish...\n”);
res = pthread_join(a_thread, &thread_result);
if (res != 0) {
perror(“Thread join failed”);
exit(EXIT_FAILURE);
}
printf(“Thread joined\n”);
sem_destroy(&bin_sem);
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg) {
sem_wait(&bin_sem);
while(strncmp(“end”, work_area, 3) != 0) {
printf(“You input %d characters\n”, strlen(work_area) -1);
sem_wait(&bin_sem);}
pthread_exit(NULL);
}
In the program above, when the semaphore is released using sem_post(), is it
possible that the fgets and the counting function in thread_function execute
simultaneously .And I think this program fails in allowing the second thread
to count the characters before the main thread reads the keyboard again.
Is that right?
The second thread will only read characters after sem_wait has returned, signaling that a sem_post has been called somewhere, so I think that is fine.
As for fgets and the counting function, those two could be running simultaneously.
I would recommend a mutex lock on the work_area variable in this case, because if the user is editing the variable in one thread while it is being read in another thread, problems will occur.
You can either use a mutex or you can use a semaphore and set the initial count on it to 1.
If you implement a mutex or use a semaphore like that though, make sure to put the mutex_lock after sema_wait, or else a deadlock may occur.
In this example you want to have a mutex around the read & writes of the shared memory.
I know this is an example, but the following code:
fgets(work_area, WORK_SIZE, stdin);
Should really be:
fgets(work_area, sizeof(work_area), stdin);
If you change the size of work_area in the future (to some other constant, etc), it's quite likely that changing this second WORK_SIZE could be missed.