Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #include <pthread.h>
- #define STATE_FREE 0
- #define STATE_WAITING 1
- #define STATE_DOING 2
- #define STATE_FINISHED 3
- #define SHARED_MEM_KEY 4242
- void clean();
- void *thread_behavior();
- void *thread_cmd_behavior();
- typedef struct{
- int id;
- int duration;
- int state; // 0 - free, 1 - waiting, 2 - doing, 3 - finished
- }process_t;
- int current_id;
- int slots_number;
- process_t *slots = NULL;
- pthread_t *threads = NULL;
- pthread_t cmd_thread = NULL;
- pthread_mutex_t *threads_mutex = NULL;
- pthread_mutex_t *state_mutex = NULL;
- int shmid = -1;
- int main(int argc, char *argv[]){
- if(argc < 3){
- printf("Usage: %s threads slots\n", argv[0]);
- exit(-1);
- }
- // Get args from cmd
- int threads_number = atoi(argv[1]);
- slots_number = atoi(argv[2]);
- printf("threads=%d, slots=%d\n", threads_number, slots_number);
- // Create the slots array (shared memory)
- shmid = shmget(SHARED_MEM_KEY, slots_number * sizeof(process_t), IPC_CREAT|0660);
- current_id = 0;
- slots = (process_t *)shmat(shmid, NULL, SHM_R|SHM_W); //malloc(slots_number * sizeof(process_t));
- if(slots == NULL){
- perror("Error while malloc.\n");
- clean();
- exit(-1);
- }
- int j;
- for(j=0; j<slots_number; j++){
- slots[j].state = STATE_FREE;
- }
- // Initialize mutex
- threads_mutex = (pthread_mutex_t *)malloc(slots_number * sizeof(pthread_mutex_t));
- if(threads_mutex == NULL){
- perror("Error while malloc.\n");
- clean();
- exit(-1);
- }
- for(j=0; j<slots_number; j++){
- if(pthread_mutex_init(&threads_mutex[j], NULL) == -1){
- perror("Error while creating mutex.\n");
- clean();
- exit(-1);
- }
- }
- state_mutex = (pthread_mutex_t *)malloc(slots_number * sizeof(pthread_mutex_t));
- if(threads_mutex == NULL){
- perror("Error while malloc.\n");
- clean();
- exit(-1);
- }
- for(j=0; j<slots_number; j++){
- if(pthread_mutex_init(&state_mutex[j], NULL) == -1){
- perror("Error while creating mutex.\n");
- clean();
- exit(-1);
- }
- }
- printf("Mutex created.\n");
- // Fork
- pid_t son_pid = fork();
- if(son_pid == -1){
- perror("Error while forking\n");
- clean();
- exit(-1);
- } else if(son_pid == 0){ // son
- int i;
- int memid = shmget(SHARED_MEM_KEY, slots_number * sizeof(process_t), 0660);
- process_t *slots_to_read = (process_t *)shmat(memid, NULL, SHM_R);
- while(1){
- for(i=0; i<slots_number; i++){
- printf("Slot %d in state %d\n", i, slots_to_read[i].state);
- }
- sleep(3);
- }
- } else{ // father
- // Create and start slots checker threads
- int k;
- threads = (pthread_t *)malloc(threads_number*sizeof(pthread_t));
- if(threads == NULL){
- perror("Error while malloc.\n");
- clean();
- exit(-1);
- }
- for(k=0; k<threads_number; k++){
- pthread_create(&threads[k], NULL, thread_behavior, NULL);
- }
- printf("Threads created: %d\n", threads_number);
- // Create and start cmd thread
- pthread_create(&cmd_thread, NULL, thread_cmd_behavior, NULL);
- pause();
- }
- }
- void clean(){
- if(shmid != -1)
- shmctl(shmid, IPC_RMID, NULL);
- // free(slots);
- if(threads != NULL)
- free(threads);
- if(threads_mutex != NULL)
- free(threads_mutex);
- if(state_mutex != NULL)
- free(threads_mutex);
- }
- void *thread_behavior(){
- int i;
- while(1){
- for(i=0; i<slots_number; i++){
- int locked = 0;
- if(pthread_mutex_lock(&state_mutex[i]) != 0){
- perror("Error while locking.\n");
- }
- locked = 1;
- if(slots[i].state == STATE_WAITING){
- if(pthread_mutex_lock(&threads_mutex[i]) != 0){
- perror("Error while locking.\n");
- }
- // printf("Founded a task to execute slot=%d, id=%d.\n", i, slots[i].id);
- slots[i].state = STATE_DOING;
- if(pthread_mutex_unlock(&state_mutex[i]) != 0){
- perror("Error while unlocking.\n");
- }
- locked = 0;
- sleep(slots[i].duration);
- // printf("Task %d finished.\n", slots[i].id);
- slots[i].state = STATE_FINISHED;
- if(pthread_mutex_unlock(&threads_mutex[i]) != 0){
- perror("Error while unlocking.\n");
- }
- }
- if(locked == 1){
- if(pthread_mutex_unlock(&state_mutex[i]) != 0){
- perror("Error while unlocking.\n");
- }
- }
- }
- }
- }
- void *thread_cmd_behavior(){
- while(1){
- int duration;
- printf("Enter the duration of a task (-1 to quit): ");
- scanf("%d", &duration);
- if(duration == -1){
- clean();
- exit(0);
- } else{
- int i;
- int slot_founded = 0;
- do{
- for(i=0; i<slots_number; i++){
- if(slots[i].state == STATE_FREE || slots[i].state == STATE_FINISHED){
- current_id++;
- slots[i].id = current_id;
- slots[i].duration = duration;
- slots[i].state = STATE_WAITING;
- printf("Task created in slot %d with id=%d and duration=%d.\n", i, slots[i].id, slots[i].duration);
- slot_founded = 1;
- break;
- }
- }
- if(!slot_founded){
- printf("Slot not founded, retrying in 1 sec.\n");
- sleep(1);
- }
- }while(!slot_founded);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement