Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stddef.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <time.h>
- #include <pthread.h>
- #include <errno.h>
- #include <signal.h>
- #define MAXLINE 4096
- #define ELAPSED(start,end) ((end).tv_sec-(start).tv_sec)+(((end).tv_nsec - (start).tv_nsec) * 1.0e-9)
- #define ERR(source) (perror(source),\
- fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
- exit(EXIT_FAILURE))
- typedef unsigned int UINT;
- typedef struct timespec timespec_t;
- typedef struct argsDivision {
- pthread_t tid;
- UINT seed;
- int *pL;
- int *pChecked;
- pthread_mutex_t *pmxL;
- pthread_mutex_t *pmxChecked;
- } argsDivision_t;
- typedef struct argsSignal {
- pthread_t tid;
- sigset_t* pMask;
- int *pQuitFlag;
- pthread_mutex_t *pmxQuitFlag;
- } argsSignal_t;
- void readArguments(int argc, char** argv, int *threadsCount);
- void* check_division(void*);
- void* sig_handler(void*);
- void cancel_threads(argsDivision_t* args, int threadsCount);
- void msleep(UINT milisec);
- int main(int argc, char** argv)
- {
- srand(time(NULL));
- int threadsCount;
- int L = 1;
- int checked = 0;
- readArguments(argc, argv, &threadsCount);
- sigset_t newMask;
- sigemptyset(&newMask);
- sigaddset(&newMask, SIGINT);
- if(pthread_sigmask(SIG_BLOCK, &newMask, NULL)) ERR("pthread_sigmask");
- int quitFlag = 0;
- pthread_mutex_t mxQuitFlag = PTHREAD_MUTEX_INITIALIZER;
- argsSignal_t args;
- args.pQuitFlag = &quitFlag;
- args.pmxQuitFlag = &mxQuitFlag;
- args.pMask = &newMask;
- if(pthread_create(&args.tid, NULL, sig_handler, &args)) ERR("pthread_create");
- pthread_mutex_t mxL = PTHREAD_MUTEX_INITIALIZER;
- pthread_mutex_t mxChecked = PTHREAD_MUTEX_INITIALIZER;
- argsDivision_t *divisions = NULL;
- if((divisions = (argsDivision_t*) malloc(sizeof(argsDivision_t) * threadsCount)) == NULL) ERR("malloc");
- for(int i = 0; i < threadsCount; ++i)
- {
- divisions[i].pL = &L;
- divisions[i].pChecked = &checked;
- divisions[i].pmxL = &mxL;
- divisions[i].pmxChecked = &mxChecked;
- divisions[i].seed = rand();
- }
- for(int i = 0; i < threadsCount; ++i)
- if(pthread_create(&divisions[i].tid, NULL, check_division, &divisions[i])) ERR("pthread_create");
- while(1)
- {
- pthread_mutex_lock(&mxQuitFlag);
- if(quitFlag == 1)
- {
- pthread_mutex_unlock(&mxQuitFlag);
- cancel_threads(divisions, threadsCount);
- break;
- }
- pthread_mutex_unlock(&mxQuitFlag);
- msleep(100);
- while(1)
- {
- pthread_mutex_lock(&mxChecked);
- if(checked == threadsCount)
- {
- checked = 0;
- pthread_mutex_unlock(&mxChecked);
- break;
- }
- pthread_mutex_unlock(&mxChecked);
- //msleep(10);
- }
- pthread_mutex_lock(&mxL);
- L += 1;
- //printf("%d\n", L);
- pthread_mutex_unlock(&mxL);
- }
- for(int i = 0; i < threadsCount; ++i)
- if(pthread_join(divisions[i].tid, NULL)) ERR("pthread_join");
- if(pthread_join(args.tid, NULL)) ERR("pthread_join");
- if(pthread_sigmask(SIG_UNBLOCK, &newMask, NULL)) ERR("pthread_sigmask");
- free(divisions);
- exit(EXIT_SUCCESS);
- }
- void readArguments(int argc, char** argv, int *threadsCount)
- {
- *threadsCount = 0;
- if (argc >= 2)
- *threadsCount = atoi(argv[1]);
- if (*threadsCount <= 0) {
- printf("Invalid value for 'threadsCount'\n");
- exit(EXIT_FAILURE);
- }
- }
- void* check_division(void* voidArgs)
- {
- pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
- argsDivision_t* args = (argsDivision_t*) voidArgs;
- int M = rand_r(&args->seed) % 99 + 2;
- int odlL = 0;
- //printf("%d\n", M);
- while(1)
- {
- pthread_mutex_lock(args->pmxL);
- if(*args->pL <= odlL)
- {
- pthread_mutex_unlock(args->pmxL);
- //msleep(10);
- continue;
- }
- pthread_mutex_lock(args->pmxChecked);
- (*args->pChecked) += 1;
- pthread_mutex_unlock(args->pmxChecked);
- odlL = *args->pL;
- pthread_mutex_unlock(args->pmxL);
- if(odlL % M == 0)
- printf("%d jest podzielne przez %d\n", odlL, M);
- msleep(100);
- }
- return NULL;
- }
- void* sig_handler(void* voidArgs)
- {
- argsSignal_t* args = (argsSignal_t*) voidArgs;
- int signo;
- while(1)
- {
- if(sigwait(args->pMask, &signo)) ERR("sigwait");
- switch(signo)
- {
- case SIGINT:
- pthread_mutex_lock(args->pmxQuitFlag);
- *args->pQuitFlag = 1;
- pthread_mutex_unlock(args->pmxQuitFlag);
- return NULL;
- default:
- printf("unexpected signal %d\n", signo);
- exit(1);
- }
- }
- return NULL;
- }
- void cancel_threads(argsDivision_t* args, int threadsCount)
- {
- for(int i = 0; i < threadsCount; ++i)
- pthread_cancel(args[i].tid);
- }
- void msleep(UINT milisec)
- {
- time_t sec = (int)(milisec / 1000);
- milisec = milisec - sec*1000;
- timespec_t req = {sec, milisec * 1000000L};
- if(nanosleep(&req, &req)) ERR("nanosleep");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement