I've use pthread for multithreded program and I've got the following situation.
When I run the code without sleep command it causes error at run time, and when I add the sleep command program runs as expected.
With sleep:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t m_writer = PTHREAD_MUTEX_INITIALIZER;
void *print_str(void *args) {
sleep(12);
char *str = (char*) args;
pthread_mutex_lock(&m_writer);
printf("%s", str);
pthread_mutex_unlock(&m_writer);
pthread_exit(NULL);
}
int main(int argc, char **argv) {
pthread_t t1;
pthread_create(&t1, NULL, print_str, "Hello\n");
pthread_mutex_lock(&m_writer);
printf("LOL\n");
pthread_mutex_unlock(&m_writer);
pthread_join(t1, NULL);
return 0;
}
Without sleep:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t m_writer = PTHREAD_MUTEX_INITIALIZER;
void *print_str(void *args) {
char *str = (char*) args;
pthread_mutex_lock(&m_writer);
printf("%s", str);
pthread_mutex_unlock(&m_writer);
pthread_exit(NULL);
}
int main(int argc, char **argv) {
pthread_t t1;
pthread_create(&t1, NULL, print_str, "Hello\n");
pthread_mutex_lock(&m_writer);
printf("LOL\n");
pthread_mutex_unlock(&m_writer);
pthread_join(t1, NULL);
return 0;
}
Error:
futex(0x559c3d3df0a0, FUTEX_WAIT_PRIVATE, 2, NULLHello
) = -1 EAGAIN (Resource temporarily unavailable)
strace shows results of system calls. Pthread functions in Linux are not system calls, they are libc functions implemented on top of (potentilally non-trivial) system calls. You are not interested in what internal system calls return. A single successfull call to ptread_mutex_lock may and sometimes does entail several failing syscalls.
In particular, pthread_mutex_lock cannot possibly result in EAGAIN in this program because there are no attempts to lock the mutex recursively, and the default mutex is not recursive in Linux anyway. The FUTEX_WAIT_PRIVATE syscall that pthread_mutex_lock uses internally can and will result in EAGAIN. This is of no interest whatsoever to the application programmer.
Related
I am trying to use pthread. In my code below I have defined two global variables (arg1 and arg2) and in the main function I start filling each element of arg2 with 1. I want the pthread to print the 101-th element of arg2 as soon as it is filled by main. But the pthread prints nothing. Actually the changes of arg1 is not followed by pthread and the pthread assumes that arg1 is 0. How can I activate a pthread so that when I write in a buffer in main, the pthread starts reading from buffer simultaneously?
Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <math.h>
#include <sys/time.h>
#include <unistd.h>
#include <assert.h>
#include <signal.h>
#include <pthread.h>
struct arg_struct {
int arg1;
int arg2[1000];
};
//volatile int arg1;
//int arg2[1000];
void *ProcessThread (void *arguments){
struct arg_struct *args = arguments;
if( args -> arg1==100) {
printf("%d", args -> arg2[ args -> arg1]);
}
pthread_exit(NULL);
return NULL;
}
void main(){
struct arg_struct args;
pthread_t thread1;
void *thread_status;
pthread_create(&thread1, NULL, ProcessThread, (void *)&args);
for ( args.arg1=0; args.arg1<1000; args.arg1++){
args.arg2[args.arg1] =1;
}
pthread_join(thread1,&thread_status);
}
The thread is terminated by the time you get to the for loop. arg1 is still not initialized in ProcessThread. You can use a while loop with the sleep function to test periodically the condition.
Hey so I'm trying to create a multithreaded program. The first thread takes in input from std in and stores it in a minheap. The second thread... well for now, all it does is print "sequencer thread works" and nothing else because it doesn't run properly.
Both threads are detached, so they should run simultaneously, and yet for some reason the second thread doesn't run until the first exits. Is it something simple I am overlooking? I'm new to multithreading.
Thanks
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include "MinHeap.h"
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* readerthread(MinHeap minheap, char eventlist[], char timestamp[])
{
char buffer[100];
char input;
int ret, len, fd;
while(1)
{
char *choice;
choice = malloc(50*sizeof(char));
fgets(choice, 50, stdin);
printf("choice = : %s", choice);
if(checkTimestamp(choice)==0)
{
pthread_mutex_lock(&mutex);
addElement(&minheap, choice);
pthread_mutex_unlock(&mutex);
}
free(choice);
printf( "min of minheap: %s\n", getMin(&minheap));
}
void* sequencerthread()
{
printf("sequencer works\n");
fflush(stdout);
pthread_exit(0);
}
int main(int argc, char *argv[])
{
if (argv < 2)
{
printf("not enough arguments. exiting...\n");
return 1;
}
char timestamp[50];
char event[50];
char eventlist[sizeof(char)+170];
int i;
char nowtimestamp[] = "2400/001/00/00/00";
MinHeap minheap;
initializeMinHeap(&minheap, intCompare, sizeof(char)*50);
strcpy(timestamp, argv[1]);
strcpy(event, argv[2]);
pthread_t ignore1, ignore2;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_create(&ignore1, &attr, readerthread(minheap, eventlist, nowtimestamp), 0);
pthread_create(&ignore2, &attr, sequencerthread, 0);
pthread_attr_destroy(&attr);
pthread_exit(0);
return (EXIT_SUCCESS);
}
This line is the problem:
pthread_create(&ignore1, &attr, readerthread(minheap, eventlist, nowtimestamp), 0);
You're calling readerthread on the main thread and passing its result to pthread_create. Since readerthread never returns, you never even get to the first call to pthread_create, let alone the second one.
You need to call it like this instead:
pthread_create(&ignore1, &attr, readerthread, &readerthread_args);
where readerthread_args is a struct encapsulating the arguments to pass to readerthread. You'll also need to change readerthread to take a single void * argument, cast it to the type of readerthread_args, and unpack the args.
You should have got a whole bunch of warnings from your compiler. Did you remember to turn them on?
Now this is just a little test, and part of a school assignment. In my code printf is not printing at least to me being able to see it. Is this a result of the thread not functioning? The print line works outside of the thread. Thank you for any help.
I am new to threading in c.
#include<stdio.h>
#include<pthread.h>
#include<string.h>
#include<stdlib.h>
void *threadServer(void *arg)
{
printf("This is the file Name: %s\n", arg);
pthread_exit(0);
}
int main(int argc, char* argv[]){
int i=1;
while(argv[i]!=NULL){
pthread_t thread;
pthread_create(&thread, NULL, threadServer,argv[i]);
i++;
}
In your code, the parent thread of execution that created another thread finishes execution without waiting for its child threads to finish. And threads, unlike processes, once the parent thread terminates, all its child threads of execution terminate as well.
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
void *threadServer(void *arg)
{
printf("This is the file Name: %s\n", (char*)arg);
pthread_exit(0);
}
int main(int argc, char* argv[]){
int i=1;
while(argv[i]!=NULL){
pthread_t thread;
pthread_create(&thread, NULL, threadServer, argv[i]);
i++;
pthread_join(thread, NULL);
}
}
Doing this will allow the thread created to run, until it finishes execution. The pthread_join will wait for the thread to complete its execution and then move ahead.
EDIT
As people did mention in the comments, it is probably worthless trying to spawn a single thread and joining it immediately, making it no better than a single thread of execution. Hence, for the sake of experimentation, the code can be modified as follows:
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
void *threadServer(void *arg)
{
printf("This is the file Name: %s\n", (char*)arg);
}
int main(int argc, char* argv[]){
int i = 1;
pthread_t thread[argc - 1];
while(i < argc)
{
pthread_create(&thread[i-1], NULL, threadServer, argv[i]);
i++;
}
for (i = 0; i < argc - 1; ++i)
{
pthread_join(thread[i], NULL);
}
}
I tried to install SIGINT handler for the child thread in the code below. I expect the child thread to print hello when it receives SIGINT from the parent process. However, nothing comes out and the program exits immediately.
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
typedef struct proxy_node_t{
pthread_t sub_thread;
pthread_t p_self;
}proxy_node;
proxy_node* proxy;
static void proxy_singnal_handler(){
printf("Hello\n");
return;
}
static void* t_consensus(void *arg){
signal(SIGINT,proxy_singnal_handler);
sleep(1);
return NULL;
}
int main(int argc, char **argv)
{
proxy = (proxy_node*)malloc(sizeof(proxy_node));
proxy->p_self = pthread_self();
pthread_create(&proxy->sub_thread,NULL,t_consensus,NULL);
pthread_kill(proxy->sub_thread,SIGINT);
sleep(1);
return 0;
}
There are several problems.
1) The signal handler signature is not correct. It should take an int whereas you define it with no parameter.
i.e.
static void proxy_singnal_handler(){
should be
static void proxy_singnal_handler(int sig){
2) You can't call functions that are not async-signal-safe from a signal handler (printf() in your case). See signal(7) for details. You can instead use write(2) to print that message:
printf("Hello\n");
can be:
write(1, "Hello\n", 6);
3) When main thread sends SIGINT, the t_consensus thread might not have even started. So, signal() may not have been installed yet. So, you need to make sure signal() is installed before pthread_kill() could send SIGINT.
Just to demonstrate it, I have added some sleep calls (see comments in the code). But please note that sleep() is not a good way to synchronization and if you intend to adapt this example then you should use a conditional variable instead.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
typedef struct proxy_node_t{
pthread_t sub_thread;
pthread_t p_self;
}proxy_node;
proxy_node* proxy;
static void proxy_singnal_handler(int sig){
write(1, "Hello\n", 6);
return;
}
static void* t_consensus(void *arg){
signal(SIGINT,proxy_singnal_handler);
while(1); /* infinite loop */
return NULL;
}
int main(int argc, char **argv)
{
proxy = (proxy_node*)malloc(sizeof(proxy_node));
proxy->p_self = pthread_self();
pthread_create(&proxy->sub_thread,NULL,t_consensus,NULL);
sleep(2); /* delay to ensure signal handler is installed */
pthread_kill(proxy->sub_thread,SIGINT);
sleep(2); /* delay to ensure signal gets executed before the process exits */
return 0;
}
Since #Maxim Egorushkin wanted to see a solution that exits gracefully and uses semaphores:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
#include <semaphore.h>
typedef struct proxy_node_t{
pthread_t sub_thread;
pthread_t p_self;
}proxy_node;
proxy_node* proxy;
static void proxy_singnal_handler(int sig)
{
write(1, "Hello\n", 6);
return;
}
sem_t sema1;
sem_t sema2;
static void* t_consensus(void *arg)
{
signal(SIGINT,proxy_singnal_handler);
sem_post(&sema1); /*notify main thread that signal-handler is installed*/
sem_wait(&sema2); /*ensure thread exists to be pthread_kill'ed, could use sigsuspend instead*/
return NULL;
}
int main(int argc, char **argv)
{
sem_init(&sema1, 0, 0);
sem_init(&sema2, 0, 0);
proxy = (proxy_node*)malloc(sizeof(proxy_node));
proxy->p_self = pthread_self();
pthread_create(&proxy->sub_thread,NULL,t_consensus,NULL);
sem_wait(&sema1); /*wait until the thread has installed the signal handler*/
pthread_kill(proxy->sub_thread,SIGINT);
sem_post(&sema2); /*not strictly necessary if the thread uses sigsuspend*/
pthread_join(proxy->sub_thread, NULL);
free(proxy); /*not strictly necessary before exiting*/
sem_destroy(&sema1);
sem_destroy(&sema2);
return 0;
}
I am practicing multi-threading.
I create two posix threads that display a text to the screen (infinite loop), but it seem only the first thread run. I modify the program without looping, first thread prints, following is second thread. It seems that my thread are not parallel, first thread has to finish before thread two start.
How can I make them parallel?
Thanks,
hdr.h
#ifndef HDR_HDR_H_
#define HDR_HDR_H_
#define HDR_HDR_H_
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#endif /* HDR_HDR_H_ */
multithread01.c
#include "../hdr/myfunc.h"
pthread_mutex_t lock;
int main(int argc, char **argv)
{
pthread_t tid01;
pthread_t tid02;
void * status01;
void * status02;
pthread_create(&tid01, NULL, PrintOut01(), NULL);
pthread_create(&tid02, NULL, PrintOut02(), NULL);
pthread_join(&tid01, &status01);
pthread_join(&tid02, &status02);
return 0;
}
myfunc.h
#ifndef HDR_MYFUNC_H_
#define HDR_MYFUNC_H_
#include "../hdr/hdr.h"
void * PrintOut01 (void);
void * PrintOut02 (void);
#endif /* HDR_MYFUNC_H_ */
myfunc.c
#include "../hdr/hdr.h"
extern pthread_mutex_t lock;
void * PrintOut01 ()
{
while (1)
{
pthread_mutex_lock(&lock);
printf ("This is thread 01\n");
pthread_mutex_unlock(&lock);
}
}
void * PrintOut02 ()
{
while (1)
{
pthread_mutex_lock(&lock);
printf ("This is thread 02\n");
pthread_mutex_unlock(&lock);
}
}
It's because you are calling the functions in your pthread_create call, you're not passing the function pointers.
Compare the incorrect
pthread_create(&tid01, NULL, PrintOut01(), NULL);
with the correct
pthread_create(&tid01, NULL, PrintOut01, NULL);
If you remove the loops in the functions, and create the threads like you do in the code in the question, then the pthread_create will use whatever you return from the functions as the pointer to the thread function, and unless you return a pointer to a function you will have undefined behavior.