This is my thread sub routine...
Here, I am creating 4 threads and passing structure as a argument to thread sub routine.
I am trying to print thread id with getid() function,
I am getting error saying "undefined reference to gettid()".
I have added necessary header files...
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#define ARRAYSIZE 17
#define NUMTHREADS 4
struct ThreadData {
int start, stop;
int* array;
};
void* squarer(void* td)
{
struct ThreadData* data=(struct ThreadData*) td;
int start=data->start;
int stop=data->stop;
int* array=data->array;
int i;
pid_t tid1;
tid1 = gettid(); //error at this statement//`
printf("tid : %d\n",tid1);
for (i=start; i<stop; i++) {
sleep(1);
array[i]=i*i;
printf("arr[%d] = [%d]\n",i,array[i]);
}
return NULL;
}
int main(void) {
int array[ARRAYSIZE];
pthread_t thread[NUMTHREADS];
struct ThreadData data[NUMTHREADS];
int i;
int tasksPerThread=(ARRAYSIZE+NUMTHREADS-1)/NUMTHREADS;
for (i=0; i<NUMTHREADS; i++) {
data[i].start=i*tasksPerThread;
data[i].stop=(i+1)*tasksPerThread;
data[i].array=array;
}
data[NUMTHREADS-1].stop=ARRAYSIZE;
for (i=0; i<NUMTHREADS; i++) {
pthread_create(&thread[i], NULL, squarer, &data[i]);
}
for (i=0; i<NUMTHREADS; i++) {
pthread_join(thread[i], NULL);
}
for (i=0; i<ARRAYSIZE; i++) {
printf("%d ", array[i]);
}
printf("\n");
return 0;
}
Try
#include <unistd.h>
#include <sys/syscall.h>
#ifdef SYS_gettid
pid_t tid = syscall(SYS_gettid);
#else
#error "SYS_gettid unavailable on this system"
#endif
Macro to be pasted (improved over previous answer):
#include <unistd.h>
#include <sys/syscall.h>
#ifndef SYS_gettid
#error "SYS_gettid unavailable on this system"
#endif
#define gettid() ((pid_t)syscall(SYS_gettid))
Example:
#include <unistd.h>
#include <sys/syscall.h>
#ifndef SYS_gettid
#error "SYS_gettid unavailable on this system"
#endif
#define gettid() ((pid_t)syscall(SYS_gettid))
#include <stdio.h>
void main()
{
printf("tid is %d\n", gettid());
}
If you're using glibc or musl, define _GNU_SOURCE to have this symbol defined by unistd.h.
I have followed the suggestions provided on errro and corrected the source
*below is the error free code *
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
#define ARRAYSIZE 17
#define NUMTHREADS 4
struct ThreadData {
int start, stop;
int* array;
};
void* squarer(void* td)
{
struct ThreadData* data=(struct ThreadData*) td;
int start=data->start;
int stop=data->stop;
int* array=data->array;
int i;
pid_t tid1;
tid1 = syscall(SYS_gettid); // here is the correct statement //
printf("tid : %d\n",tid1);
for (i=start; i<stop; i++) {
sleep(1);
array[i]=i*i;
printf("arr[%d] = [%d]\n",i,array[i]);
}
return NULL;
}
int main(void) {
int array[ARRAYSIZE];
pthread_t thread[NUMTHREADS];
struct ThreadData data[NUMTHREADS];
int i;
int tasksPerThread=(ARRAYSIZE+NUMTHREADS-1)/NUMTHREADS;
for (i=0; i<NUMTHREADS; i++) {
data[i].start=i*tasksPerThread;
data[i].stop=(i+1)*tasksPerThread;
data[i].array=array;
}
data[NUMTHREADS-1].stop=ARRAYSIZE;
for (i=0; i<NUMTHREADS; i++) {
pthread_create(&thread[i], NULL, squarer, &data[i]);
}
for (i=0; i<NUMTHREADS; i++) {
pthread_join(thread[i], NULL);
}
for (i=0; i<ARRAYSIZE; i++) {
printf("%d ", array[i]);
}
printf("\n");
return 0;
}
Related
A for loop in thread_create terminates and does not print anything.
When I debug in gdb, watch new thread terminate immediately.
I don't know why?
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void* myturn(void * arg){
for(int j; ; j++){
sleep(3);
fprintf(stderr, "my turn\n");
printf("my turn\n");
//pthread_exit(0);
}
sleep(3);
return NULL;
}
int yourturn(){
for(int i; i<3; i++){
sleep(2);
printf("your turn\n");
}
}
int main(int arg, char * argv[]){
pthread_t new_thread;
pthread_create(&new_thread, NULL, myturn, NULL);
// myturn();
yourturn();
pthread_join(new_thread, NULL);
return 0;
}
I modified you code a little and its working:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void* myturn(void * arg){
int j = 0;
for(j=0; j<10; j++){
sleep(1);
fprintf(stderr, "my turn\n");
printf("my turn\n");
//pthread_exit(0);
}
sleep(1);
return NULL;
}
int yourturn(){
int i = 0;
for(i=0; i<30; i++){
sleep(2);
printf("your turn\n");
}
}
int main(int arg, char * argv[]){
pthread_t new_thread;
pthread_create(&new_thread, NULL, myturn, NULL);
// myturn();
yourturn();
pthread_join(new_thread, NULL);
return 0;
}
The problems I found were that you can't initialize a variable in the loop and you have to describe more itens in the loop.
Errors:
for(int j; ; j++){
for(int i; i<3; i++){
Try after initializing the loop variables i and j to zero or something.
So I have three files: Pellets.c, Fish.c, and SwimMill.c. SwimMill calls Pellets and Fish, which should fork. However, when I try to fork Pellets, i get an error saying "Pellet fork failed: Bad Address". Anyone know what the problem is?
include.h
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#define SHM_SIZE 1000
int shmid;
int *shm;
pid_t fish;
pid_t pellet;
void attachSharedMemory() {
key_t key = ftok("SwimMill.c", 'b'); //generate random key
shmid = shmget(key, SHM_SIZE, IPC_CREAT|0666);
shm = shmat(shmid, NULL, 0);
}
SwimMill.c
// Uses both fish and pellets, 30 seconds, then print it out
// Create pellets at random intervals, from 0x80
// Eating --> Get rid of most significant bit
// Use shared memory for fish and pellet position only
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include "include.h"
#define SHM_SIZE 1000
void printGrid(int*);
void handler(int);
void killProgram(pid_t, pid_t, int*, int);
pid_t fish;
pid_t pellet;
int main(int argc, char* argv[]) {
int timer = 0;
attachSharedMemory(); // from include.h
signal(SIGINT, handler);
// Initializing the shared memory to prevent segmentation fault
// for (int i = 0; i < SHM_SIZE; i++){
// shm[i] = -1;
// }
srand(time(NULL));
fish = fork();
if (fish == -1) {
perror("Fish fork failed1");
exit(1);
} else if (fish == 0) {
execv("Fish", argv);
perror("Fish exec failed");
exit(1);
}
while(timer <= 30){
pellet = fork();
if (pellet == -1) {
perror("Pellet Fork failed1");
exit(1);
} else if (pellet == 0) {
execv("Pellets", argv);
perror("Pellets Fork failed");
exit(1);
}
printGrid(shm);
sleep(1);
printf("Timer: %d\n", timer);
timer++;
}
killProgram(fish, pellet, shm, shmid);
getchar(); // Pause consol
return 0;
}
void printGrid(int* shm) {
int row = 10;
int column = 10;
char (*stream)[row][column]; //2D Dimensional array, fish can only move last row of 2d
//Initializing grid first
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
(*stream)[i][j] = '~';
}
}
printf("Fish: %d \n", shm[0]);
printf("Shm2 is: %d \n", shm[1] );
for (int k = 1; k < 20; k++) {
(*stream)[shm[k]/10][shm[k]%10] = 'O'; // pellets
}
(*stream)[shm[0]/10][shm[0]%10] = 'Y'; // Fish
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
printf("%c ", (*stream)[i][j]);
}
printf("\n");
}
}
void killProgram(pid_t fish, pid_t pellet, int *shm, int shmid) {
kill(fish,SIGUSR1);
kill(pellet, SIGUSR1);
sleep(5);
shmdt(shm);
shmctl(shmid, IPC_RMID, NULL);
printf("Program finished! \n");
}
void handler(int num ) {
kill(fish,SIGUSR1);
kill(pellet, SIGUSR1);
shmdt(shm);
shmctl(shmid, IPC_RMID, NULL);
perror(" Interrupt signal is pressed!! \n");
exit(1);
}
Pellets.c
// Multiple pellets
//Process ID, position, eaten/misse
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include "include.h"
#define SHM_SIZE 1000
void handler(int);
void eatPellet();
void missPellet();
int main(int argc, char* argv[]) {
signal(SIGINT, handler);
attachSharedMemory();
srand(time(NULL));
int i = 1; // 1 - 19 are pellets
for (; i < 20; i++) {
int pelletPosition = rand() % 9 ; // random number from 0 - 9
if (shm[i] == -1){
// printf("hello %d \n", pelletPosition);
shm[i] = pelletPosition;
}
break;
}
while(1) {
printf("helloasd %d \n", shm[i]);
printf("i: %d \n", i);
if (shm[i] < 90) {
shm[i] += 10;
}
else if (shm[i] == shm[0]) {
eatPellet();
printf("Position: %d\n", shm[i] );
break;
// EATEN and KILL
}
else {
// KIll process, terminate
missPellet();
printf("Position: %d\n", shm[i] );
break;
}
// printf("%d\n",shm[i] );
i++;
sleep(1);
}
shmdt(shm);
return 0;
}
void handler(int num) {
shmdt(shm);
exit(1);
}
I looked at other stack overflow questions, and it seems that they problems because they didn't terminate with a NULL? I think the problem lies inside Pellets.c, but I can't seem to figure it out. Thanks.
I'm having problems passing a string to a thread function using pthread_create
I get strange charactes when i run the progam
here is the code
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
#include <sys/stat.h>
#define NTHREADS 3
void *myFun(void *ptr){
char * string;
string = (char *) ptr;
printf("string: %s\n", string);
return NULL;
}
int main(int argc, char *argv[]){
pthread_t threads[NTHREADS];
char* thread_args[NTHREADS];
int i;
char* string;
/* spawn threads */
for (i=0; i<NTHREADS; ++i){
string = "file1.txt";
thread_args[i] = string;
if(pthread_create(&threads[i], NULL, myFun, (void *) &thread_args[i]) != 0){
printf("Error creating thread\n");
exit(1);
}
}
/* Wait for threads to finish */
for (i=0; i<NTHREADS; ++i) {
pthread_join(threads[i], NULL);
}
return 0;
}
I can pass a int without problems doing a cast to int in the same way i did in the code, but with char it is not working.
Pass the pointer, not the address of the pointer.
if(pthread_create(&threads[i], NULL, myFun, (void *) thread_args[i])
^
I'm currently being introduced to the concept of threading programs, and have been given an assignment to simulate a stockmarket using threads and semaphores. Here is the code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <pthread.h>
#define NUM_WRITERS 5
#define NUM_READERS 5
#define STOCKLIST_SIZE 10
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
sem_t stop_writers;
typedef struct
{ int readers;
int slots[STOCKLIST_SIZE];
} mem_structure;
int id[NUM_READERS + NUM_WRITERS];
mem_structure *stocklist;
pthread_t thr[NUM_WRITERS + NUM_READERS];
void init(){
sem_init(&stop_writers, 0, 1);
}
void cleanup(int signo) // clean up resources by pressing Ctrl-C
{ sem_destroy(&stop_writers);
printf("Closing...\n");
exit(0);
}
void write_stock(int n_writer)
{
int stock = (int)(rand()%STOCKLIST_SIZE);
int stock_value = 1 + (int)(100.0 * rand()/(RAND_MAX + 1.0));
stocklist->slots[stock] = stock_value;
fprintf(stderr, "Stock %d updated by BROKER %d to %d\n", stock, n_writer, stock_value);
}
void* writer(void* id){
int my_id = *((int*) id);
int i = my_id;
while (1)
{
pthread_mutex_lock(&mutex);
sem_wait(&stop_writers);
write_stock(i);
pthread_mutex_unlock(&mutex);
sem_post(&stop_writers);
sleep(1);
++i;
}
}
void read_stock(int pos, int n_reader){
fprintf(stderr, "Stock %d read by client %d = %d.\n", pos, n_reader, stocklist->slots[pos]);
}
void* reader(void* id){
int my_id = *((int*) id);
int i = my_id;
while (1)
{ sem_wait(&stop_writers);
read_stock((int)(rand()%STOCKLIST_SIZE), i);
sem_post(&stop_writers);
sleep(1 + (int) (3.0 * rand() / (RAND_MAX + 1.0)));
++i;
}
}
void monitor() // main process monitors the reception of Ctrl-C
{
struct sigaction act;
act.sa_handler = cleanup;
act.sa_flags = 0;
if ((sigemptyset(&act.sa_mask) == -1) ||
(sigaction(SIGINT, &act, NULL) == -1))
perror("Failed to set SIGINT to handle Ctrl-C");
while(1){
sleep(5);
printf("Still working...\n");
}
exit(0);
}
int main(void)
{ int i, j;
init();
for (i = 0; i < NUM_WRITERS; ++i){
id[i] = i;
pthread_create(&thr[i], NULL, writer, &id[i]);}
for (j = i; j < NUM_READERS; ++j){
id[j] = j;
pthread_create(&thr[j], NULL, reader, &id[j]);}
stocklist->readers = 0;
pthread_exit(NULL);
monitor();
return 0;
}
This is giving me a segmentation fault pretty much as soon as main() begins, with the creation of a thread... Since it's not code that I've created from root, I'm having trouble backtracing the error and fixing it - it would be great if there was someone who could take a look and maybe give me some hints
Thank you!
EDIT
Fixed the problem, thanks to your help :)
I initialized stocklist on init(),
void init(){
sem_init(&stop_writers, 0, 1);
stocklist = (mem_structure*)malloc(sizeof(mem_structure));
}
And changed the second cicle in main(),
for (j = i; j < NUM_READERS+NUM_WRITERS; ++j){
id[j] = j;
pthread_create(&thr[j], NULL, reader, &id[j]);}
Thanks
Here's what I did to track down the problem:
gcc -g program.c -lpthread
gdb a.out
run
Output:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7feeb70 (LWP 23060)]
0x08048834 in write_stock (n_writer=0) at program.c:44
44 stocklist->slots[stock] = stock_value;
Looks like the problem is here:
stocklist->slots[stock] = stock_value;
I want to use the SIGNAL SIGSUR1 to communicate between two processes, but I get the compiler error:
error: ‘SIGSUR1’ was not declared in this scope .
What's the fix?
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
void cursor(int y)
{
int i;
printf("%c[%d;%df",0x1B,y,0);
}
void handle(int fd,int turtle_current_pos){
fcntl(fd,F_SETFL,O_NONBLOCK);
write(fd,&turtle_current_pos,sizeof(int));
}
int getdist(int fd,int hare_pos,int max_dist)
{
int r,n;
raise(0,SIGSUR1);
fcntl(fd,F_SETFL,O_NONBLOCK);
if((n=read(fd,&r,sizeof(int)))){
if((hare_pos-r-max_dist)>0)
return 0;
else
return 1;
}
}
void print(char b,int a){
fflush(stdout);
if(b=='T') cursor(10);
else cursor(15);
for(int i=0;i<a;i++) printf(" ");
printf("%c\n",b);
}
void turtle(int fd,int sec1,int turtle_speed){
signal(SIGSUR1,handle);
struct timeval b;
int flag=1,turtle_current_pos,turtle_previous_pos=0,sec2;
turtle_current_pos=0;
while(turtle_current_pos<100){
sleep(2);
gettimeofday(&b,NULL);
sec2=b.tv_sec;
//printf("%d\n",sec2);
turtle_current_pos=(sec2-sec1)*turtle_speed;
fflush(stdout);
if((turtle_current_pos-turtle_previous_pos)>=1){
turtle_previous_pos=turtle_current_pos;
print('T',turtle_previous_pos);
}
}
}
int main(){
system("clear");
pid_t pid,God_pid,hare_pid,Report_pid;
int max_dist=10,sleep_time=1,pipe1[2],speed_hare=5,speed_turtle=1;
pipe(pipe1);
pid=fork();
if(pid!=0){
int hare_current_pos=0,hare_previous_pos=0,sec1,sec2;
struct timeval n;
gettimeofday(&n,NULL);
sec1=n.tv_sec;
sec2=sec1;
close(pipe1[1]);
while(hare_current_pos<100){
sleep(1);
if(getdist(pipe1[0],hare_current_pos,max_dist)==0){
sleep(sleep_time);
gettimeofday(&n,NULL);
sec1=n.tv_sec;
sec2=sec1;
fflush(stdout);
}
else{
gettimeofday(&n,NULL);
sec2=n.tv_sec;
gettimeofday(&n,NULL);
hare_current_pos+=speed_hare*(sec2-sec1);
//printf("\n%d",hare_current_pos);
fflush(stdout);
if(hare_current_pos-hare_previous_pos){
print('H',hare_current_pos);
hare_previous_pos=hare_current_pos;
}
}
}
}
else{
close(pipe1[0]);
struct timeval b;
gettimeofday(&b,NULL);
fflush(stdout);
turtle(pipe1[1],b.tv_sec,speed_turtle);
}
}
Try SIGUSR1 instead.