I want a threaded while loop that forever increments i. Why does it stop prematurely?
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
void *increment () {
int i = 0;
while (1) {
i++;
printf("Number: %d", i);
}
}
int main (int argc, char **argv) {
if (argc <= 1) {
fprintf(stderr, "Invalid params\n");
exit(-1);
}
int num_threads = atoi(argv[1]);
pthread_t thread[num_threads];
for (int i = 0; i < num_threads; i++) {
pthread_create(&thread[i], NULL, &increment, argv[1]);
}
return 0;
}
just put
while(1);
before the return in main if you just want the created thread to run forever
E.g.
int main (int argc, char **argv) {
if (argc <= 1) {
fprintf(stderr, "Invalid params\n");
exit(-1);
}
int num_threads = atoi(argv[1]);
pthread_t thread[num_threads];
for (int i = 0; i < num_threads; i++) {
pthread_create(&thread[i], NULL, &increment, argv[1]);
}
while(1) ; // don't exit the main thread
// while (1) sleep(1000) ; // would be better
return 0;
}
Related
I am trying to solve the problem of consumer-producer with condition variables,
i just want to know if my code resolves the problem correctly.
PS:i can put while(1) instead of while(x<100) but i want to see the execution and check if there is missed numbers,
my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#define THREAD_NUM 2
pthread_cond_t full;
pthread_cond_t empty;
pthread_mutex_t mutexBuffer;
int buffer[10];
int count = 0;//the index of where the consume/produce should be in the buffer
void* producer(void* args) {
// int i=1;
int x = 1;
while (x<100)
{
// Produce
// Add to the buffer
pthread_mutex_lock(&mutexBuffer);
if (count<10)
{
buffer[count]= x;
count++;
pthread_cond_signal(&empty);
x++;
}
else
{
pthread_cond_wait(&full,&mutexBuffer);
buffer[count]= x;
count++;
x++;
}
pthread_mutex_unlock(&mutexBuffer);
}
}
void* consumer(void* args) {
int cpt=0;//to stop the while after execution 100 times
while (1) {
int y=-1;
// Remove from the buffer
pthread_mutex_lock(&mutexBuffer);
if (count>0)
{
y = buffer[count - 1];
count--;
pthread_cond_signal(&full);
}
else
{
pthread_cond_wait(&empty,&mutexBuffer);
y = buffer[count - 1];
count--;
printf("nothing is lost!\n");
}
printf("Got %d\n", y);
cpt++;
pthread_mutex_unlock(&mutexBuffer);
if(cpt==99)break;
}
}
int main(int argc, char* argv[]) {
srand(time(NULL));
pthread_t th[THREAD_NUM];
pthread_mutex_init(&mutexBuffer, NULL);
int i;
for (i = 0; i < THREAD_NUM; i++) {
if (i%2==0) {
if (pthread_create(&th[i], NULL, &producer, NULL) != 0) {
perror("Failed to create thread");
}
} else {
if (pthread_create(&th[i], NULL, &consumer, NULL) != 0) {
perror("Failed to create thread");
}
}
}
for (i = 0; i < THREAD_NUM; i++) {
if (pthread_join(th[i], NULL) != 0) {
perror("Failed to join thread");
}
}
pthread_mutex_destroy(&mutexBuffer);
return 0;
}
and i have a question also,When using semaphore is better than condition variable,or the inverse?
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.
My program's desired functionality:
Using the command line user inputs N and M. N is the number of new threads that will be created and M is the number of how much every thread increments the global variable A.
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
static int A = 0;
void *Thread(void* x){
int i;
int n = *((int*)x);
for (i = 0; i<n; i++){
A++;
}
}
int main(int argc, char* argv[]){
int i;
int N = atoi(argv[1]);
int M = atoi(argv[2]);
pthread_t *thread = (pthread_t *) malloc(sizeof(pthread_t)*N);
if(!thread){
printf("No memory\n");
exit(2);
}
for (i = 0; i< N; i++){
if (pthread_create(&thread[i], NULL, Thread, &M)){
printf("Not able to create a thread\n");
exit(1);
}
}
for(i = 0; i< N; i++)
pthread_join(thread[i], NULL);
printf("A = %d\n", A);
return 0;
}
The problem is that every time I run it there's a different output.
Screenshot of my terminal when i run the program multiple times in a row
The problem is that you are creating multiple threads that in parallel are trying to modify your static A global variable at the same time, without any kind of protection.
That means that depending on the scheduling of the threads, the changes on your global variable will not be atomic, producing this effect.
You can solve this with a mutex, declare it with:
pthread_mutex_t mutex;
And initialise / release it with pthread_mutex_init and pthread_mutex_destroy.
Inside of the thread, before doing the change protect the resource to change with pthread_mutex_lock, and release it with pthread_mutex_unlock. So the code will be changed like this:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
static int A = 0;
pthread_mutex_t mutex;
void *Thread(void* x){
int i;
int n = *((int*)x);
pthread_mutex_lock(&mutex);
A += n;
pthread_mutex_unlock(&mutex);
}
int main(int argc, char* argv[]){
int i;
int N = atoi(argv[1]);
int M = atoi(argv[2]);
pthread_mutex_init(&mutex, NULL);
pthread_t *thread = (pthread_t *) malloc(sizeof(pthread_t)*N);
if(!thread){
printf("No memory\n");
exit(2);
}
for (i = 0; i< N; i++){
if (pthread_create(&thread[i], NULL, Thread, &M)){
printf("Not able to create a thread\n");
exit(1);
}
}
for(i = 0; i< N; i++)
pthread_join(thread[i], NULL);
printf("A = %d\n", A);
pthread_mutex_destroy(&mutex);
return 0;
}
I use pthread_create to create 10 child threads, passes an integer to the thread_func
#define THREAD_NUM 10
void *thread_func(void *arg)
{
int v = (int)arg;
printf("v = %d\n", v);
return (void*)0;
}
int main(int argc, const char *argv[])
{
pthread_t pids[THREAD_NUM];
int rv;
int i;
for (i = 0; i < THREAD_NUM; i++) {
rv = pthread_create(&pids[i], NULL, thread_func, (void*)i);
if (rv != 0) {
perror("failed to create child thread");
return 1;
}
}
return 0;
}
I was wondering why it outputs different result everytime not just
v = 1
v = 2
...
v = 9
You have to wait for all the threads to complete in the main using pthread_join, only then u can see all of them display some value
#include <stdio.h>
#include <pthread.h>
#define THREAD_NUM 10
void *thread_func(void *arg)
{
int v = (int)arg;
printf("v = %d\n", v);
return (void*)0;
}
int main(int argc, const char *argv[])
{
pthread_t pids[THREAD_NUM];
int rv;
int i;
for (i = 0; i < THREAD_NUM; i++) {
rv = pthread_create(&pids[i], NULL, thread_func, (void*)i);
if (rv != 0) {
perror("failed to create child thread");
return 1;
}
}
for (i = 0; i < THREAD_NUM; i++) {
pthread_join(pids[i], NULL);
}
return 0;
}
Sample run output:
[root#fc ~]# ./a.out
v = 0
v = 2
v = 4
v = 6
v = 7
v = 8
v = 9
v = 5
v = 3
v = 1
I think your question is why it is not printing them in order like v=1 v = 2 ... v = 9. That is because the kernel schedules the threads and they can be scheduled in any order. If you want synchronized output you need to use locks and condition variables.
In my case I am having proper out put.
I have done some modification. Can you give a try to it?
#include <stdio.h>
#include <pthread.h>
#define THREAD_NUM 10
void *thread_func(void *arg)
{
int v = *(int *)arg;
printf("v = %d\n", v);
return (void*)0;
}
int main(int argc, const char *argv[])
{
pthread_t pids[THREAD_NUM];
int rv;
int i;
for (i = 0; i < THREAD_NUM; i++) {
rv = pthread_create(&pids[i], NULL, thread_func, (void*)&i);
if (rv != 0) {
perror("failed to create child thread");
return 1;
}
}
return 0;
}
Briefly, echo of the threads in your program is an independent scheduling unit, which means they can actually or virtually run parallelly in an order determined by the scheduler in your operating system kernel, and this order changes run to run according to your system circumstances at that time.