Update ch3_fork a small bug, and add pthread sample code
1 files modified
5 files added
| | |
| | | rv=write(clifd, MSG_STR, strlen(MSG_STR)); |
| | | if(rv < 0) |
| | | { |
| | | printf("Write to client by sockfd[%d] failure: %s\n", sockfd, strerror(errno)); |
| | | printf("Write to client by sockfd[%d] failure: %s\n", clifd, strerror(errno)); |
| | | close(clifd); |
| | | exit(0); |
| | | } |
New file |
| | |
| | | #include <stdio.h> |
| | | #include <string.h> |
| | | #include <unistd.h> |
| | | #include <string.h> |
| | | #include <errno.h> |
| | | #include <syslog.h> |
| | | #include <libgen.h> /* basename() */ |
| | | |
| | | int main(int argc, char **argv) |
| | | { |
| | | char *progname = basename(argv[0]); |
| | | |
| | | if( daemon(0, 0) < 0) |
| | | { |
| | | printf("Program daemon() failure: %s\n", strerror(errno)); |
| | | return -1; |
| | | } |
| | | openlog("daemon", LOG_CONS | LOG_PID, 0); |
| | | syslog(LOG_NOTICE, "Program '%s'start running\n", progname); |
| | | syslog(LOG_WARNING, "Program '%s' running with a warnning message\n", progname ); |
| | | syslog(LOG_EMERG, "Program '%s' running with a emergency message\n", progname ); |
| | | while(1) |
| | | { |
| | | //Do Something here |
| | | ; |
| | | } |
| | | |
| | | syslog(LOG_NOTICE, "Program '%s' stop running\n", progname); |
| | | closelog(); |
| | | |
| | | return 0; |
| | | } |
New file |
| | |
| | | #include <stdio.h> |
| | | #include <string.h> |
| | | #include <unistd.h> |
| | | #include <signal.h> |
| | | #include <stdlib.h> |
| | | #include <execinfo.h> |
| | | |
| | | int g_sigstop = 0; |
| | | |
| | | void signal_stop(int signum) |
| | | { |
| | | if( SIGTERM == signum ) |
| | | { |
| | | printf("SIGTERM signal detected\n"); |
| | | } |
| | | else if( SIGALRM == signum ) |
| | | { |
| | | printf("SIGALRM signal detected\n"); |
| | | g_sigstop = 1; |
| | | } |
| | | } |
| | | |
| | | void signal_user(int signum) |
| | | { |
| | | if(SIGUSR1 == signum) |
| | | { |
| | | printf("SIGUSR1 signal detected\n"); |
| | | } |
| | | else if(SIGUSR2 == signum) |
| | | { |
| | | printf("SIGUSR2 signal detected\n"); |
| | | } |
| | | |
| | | g_sigstop = 1; |
| | | } |
| | | |
| | | void signal_code(int signum) |
| | | { |
| | | if(SIGBUS == signum) |
| | | { |
| | | printf("SIGBUS signal detected\n"); |
| | | } |
| | | else if(SIGILL == signum) |
| | | { |
| | | printf("SIGILL signal detected\n"); |
| | | } |
| | | else if(SIGSEGV == signum) |
| | | { |
| | | printf("SIGSEGV signal detected\n"); |
| | | } |
| | | |
| | | exit(-1); |
| | | } |
| | | |
| | | int main(int argc, char **argv) |
| | | { |
| | | char *ptr=NULL; |
| | | struct sigaction sigact, sigign; |
| | | |
| | | /*+--------------------------------------+ |
| | | *| Method1: Use signal() install signal | |
| | | *+--------------------------------------+*/ |
| | | |
| | | signal(SIGTERM, signal_stop); |
| | | signal(SIGALRM, signal_stop); |
| | | |
| | | signal(SIGBUS, signal_code); |
| | | signal(SIGILL, signal_code); |
| | | signal(SIGSEGV, signal_code); |
| | | |
| | | /*+-----------------------------------------+ |
| | | *| Method2: Use sigaction() install signal | |
| | | *+-----------------------------------------+*/ |
| | | |
| | | /* Initialize the catch signal structure. */ |
| | | sigemptyset(&sigact.sa_mask); |
| | | sigact.sa_flags = 0; |
| | | sigact.sa_handler = signal_user; |
| | | |
| | | /* Setup the ignore signal. */ |
| | | sigemptyset(&sigign.sa_mask); |
| | | sigign.sa_flags = 0; |
| | | sigign.sa_handler = SIG_IGN; |
| | | |
| | | sigaction(SIGINT, &sigign, 0); /* ignore SIGINT signal by CTRL+C */ |
| | | |
| | | sigaction(SIGUSR1, &sigact, 0); /* catch SIGUSR1 */ |
| | | sigaction(SIGUSR2, &sigact, 0); /* catch SIGUSR1 */ |
| | | |
| | | |
| | | printf("Program start running for 20 seconds...\n"); |
| | | alarm(20); |
| | | |
| | | while( !g_sigstop ) |
| | | { |
| | | ; |
| | | } |
| | | |
| | | printf("Program start stop running...\n"); |
| | | |
| | | printf("Invalid pointer operator will raise SIGSEGV signal\n"); |
| | | *ptr = 'h'; |
| | | |
| | | return 0; |
| | | } |
New file |
| | |
| | | #include <stdio.h> |
| | | #include <errno.h> |
| | | #include <string.h> |
| | | #include <unistd.h> |
| | | #include <sys/types.h> |
| | | #include <sys/socket.h> |
| | | #include <arpa/inet.h> |
| | | #include <stdlib.h> |
| | | #include <getopt.h> |
| | | #include <pthread.h> |
| | | |
| | | #define MSG_STR "Hello LingYun IoT Studio Client\n" |
| | | |
| | | typedef void *(THREAD_BODY) (void *thread_arg); |
| | | |
| | | void *thread_worker(void *ctx); |
| | | int thread_start(pthread_t * thread_id, THREAD_BODY * thread_workbody, void *thread_arg); |
| | | |
| | | |
| | | void print_usage(char *progname) |
| | | { |
| | | printf("%s usage: \n", progname); |
| | | printf("-p(--port): sepcify server listen port.\n"); |
| | | printf("-h(--Help): print this help information.\n"); |
| | | |
| | | return ; |
| | | } |
| | | |
| | | |
| | | int main(int argc, char **argv) |
| | | { |
| | | int sockfd = -1; |
| | | int rv = -1; |
| | | struct sockaddr_in servaddr; |
| | | struct sockaddr_in cliaddr; |
| | | socklen_t len; |
| | | int port = 0; |
| | | int clifd; |
| | | int ch; |
| | | int on = 1; |
| | | pthread_t tid; |
| | | |
| | | struct option opts[] = { |
| | | {"port", required_argument, NULL, 'p'}, |
| | | {"help", no_argument, NULL, 'h'}, |
| | | {NULL, 0, NULL, 0} |
| | | }; |
| | | |
| | | while( (ch=getopt_long(argc, argv, "p:h", opts, NULL)) != -1 ) |
| | | { |
| | | switch(ch) |
| | | { |
| | | case 'p': |
| | | port=atoi(optarg); |
| | | break; |
| | | |
| | | case 'h': |
| | | print_usage(argv[0]); |
| | | return 0; |
| | | } |
| | | |
| | | } |
| | | |
| | | if( !port ) |
| | | { |
| | | print_usage(argv[0]); |
| | | return 0; |
| | | } |
| | | |
| | | sockfd=socket(AF_INET, SOCK_STREAM, 0); |
| | | if(sockfd < 0) |
| | | { |
| | | printf("Create socket failure: %s\n", strerror(errno)); |
| | | return -1; |
| | | } |
| | | printf("Create socket[%d] successfully!\n", sockfd); |
| | | |
| | | setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); |
| | | |
| | | memset(&servaddr, 0, sizeof(servaddr)); |
| | | servaddr.sin_family=AF_INET; |
| | | servaddr.sin_port = htons(port); |
| | | servaddr.sin_addr.s_addr = htonl(INADDR_ANY); |
| | | //inet_aton("192.168.0.16", &servaddr.sin_addr); |
| | | |
| | | rv=bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); |
| | | if(rv < 0) |
| | | { |
| | | printf("Socket[%d] bind on port[%d] failure: %s\n", sockfd, port, strerror(errno)); |
| | | return -2; |
| | | } |
| | | |
| | | listen(sockfd, 13); |
| | | printf("Start to listen on port [%d]\n", port); |
| | | |
| | | while(1) |
| | | { |
| | | printf("Start accept new client incoming...\n"); |
| | | |
| | | clifd=accept(sockfd, (struct sockaddr *)&cliaddr, &len); |
| | | if(clifd < 0) |
| | | { |
| | | printf("Accept new client failure: %s\n", strerror(errno)); |
| | | continue; |
| | | } |
| | | |
| | | printf("Accept new client[%s:%d] successfully\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port)); |
| | | |
| | | thread_start(&tid, thread_worker, &clifd); |
| | | } |
| | | |
| | | |
| | | close(sockfd); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int thread_start(pthread_t * thread_id, THREAD_BODY * thread_workbody, void *thread_arg) |
| | | { |
| | | int rv = -1; |
| | | pthread_attr_t thread_attr; |
| | | |
| | | if( pthread_attr_init(&thread_attr) ) |
| | | { |
| | | printf("pthread_attr_init() failure: %s\n", strerror(errno)); |
| | | goto CleanUp; |
| | | } |
| | | |
| | | if( pthread_attr_setstacksize(&thread_attr, 120*1024) ) |
| | | { |
| | | printf("pthread_attr_setstacksize() failure: %s\n", strerror(errno)); |
| | | goto CleanUp; |
| | | } |
| | | |
| | | if( pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED) ) |
| | | { |
| | | printf("pthread_attr_setdetachstate() failure: %s\n", strerror(errno)); |
| | | goto CleanUp; |
| | | } |
| | | |
| | | /* Create the thread */ |
| | | if( pthread_create(thread_id, &thread_attr, thread_workbody, thread_arg) ) |
| | | { |
| | | printf("Create thread failure: %s\n", strerror(errno)); |
| | | goto CleanUp; |
| | | } |
| | | |
| | | rv = 0; |
| | | |
| | | CleanUp: |
| | | |
| | | /* Destroy the attributes of thread */ |
| | | pthread_attr_destroy(&thread_attr); |
| | | return rv; |
| | | } |
| | | |
| | | void *thread_worker(void *ctx) |
| | | { |
| | | int clifd; |
| | | int rv; |
| | | char buf[1024]; |
| | | |
| | | if( !ctx ) |
| | | { |
| | | printf("Invalid input arguments in %s()\n", __FUNCTION__); |
| | | pthread_exit(NULL); |
| | | } |
| | | |
| | | clifd = *(int *)ctx; |
| | | |
| | | printf("Child thread start to commuicate with socket client...\n"); |
| | | |
| | | while(1) |
| | | { |
| | | memset(buf, 0, sizeof(buf)); |
| | | rv=read(clifd, buf, sizeof(buf)); |
| | | if( rv < 0) |
| | | { |
| | | printf("Read data from client sockfd[%d] failure: %s\n", clifd, strerror(errno)); |
| | | close(clifd); |
| | | pthread_exit(NULL); |
| | | } |
| | | else if( rv == 0) |
| | | { |
| | | printf("Socket[%d] get disconnected\n", clifd); |
| | | close(clifd); |
| | | pthread_exit(NULL); |
| | | } |
| | | else if( rv > 0 ) |
| | | { |
| | | printf("Read %d bytes data from Server: %s\n", rv, buf); |
| | | } |
| | | |
| | | rv=write(clifd, buf, rv); |
| | | if(rv < 0) |
| | | { |
| | | printf("Write to client by sockfd[%d] failure: %s\n", clifd, strerror(errno)); |
| | | close(clifd); |
| | | pthread_exit(NULL); |
| | | } |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | #include <stdio.h> |
| | | #include <string.h> |
| | | #include <errno.h> |
| | | #include <stdlib.h> |
| | | #include <unistd.h> |
| | | #include <pthread.h> |
| | | |
| | | void *thread_worker1(void *args); |
| | | void *thread_worker2(void *args); |
| | | |
| | | int main(int argc, char **argv) |
| | | { |
| | | int shared_var = 1000; |
| | | pthread_t tid; |
| | | pthread_attr_t thread_attr; |
| | | |
| | | |
| | | if( pthread_attr_init(&thread_attr) ) |
| | | { |
| | | printf("pthread_attr_init() failure: %s\n", strerror(errno)); |
| | | return -1; |
| | | } |
| | | |
| | | if( pthread_attr_setstacksize(&thread_attr, 120*1024) ) |
| | | { |
| | | printf("pthread_attr_setstacksize() failure: %s\n", strerror(errno)); |
| | | return -1; |
| | | } |
| | | |
| | | if( pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED) ) |
| | | { |
| | | printf("pthread_attr_setdetachstate() failure: %s\n", strerror(errno)); |
| | | return -1; |
| | | } |
| | | |
| | | pthread_create(&tid, &thread_attr, thread_worker1, &shared_var); |
| | | printf("Thread worker1 tid[%ld] created ok\n", tid); |
| | | |
| | | pthread_create(&tid, NULL, thread_worker2, &shared_var); |
| | | printf("Thread worker2 tid[%ld] created ok\n", tid); |
| | | |
| | | pthread_attr_destroy(&thread_attr); |
| | | |
| | | /* Wait until thread worker2 exit() */ |
| | | pthread_join(tid, NULL); |
| | | |
| | | |
| | | while(1) |
| | | { |
| | | printf("Main/Control thread shared_var: %d\n", shared_var); |
| | | sleep(10); |
| | | } |
| | | } |
| | | |
| | | void *thread_worker1(void *args) |
| | | { |
| | | int *ptr = (int *)args; |
| | | |
| | | if( !args ) |
| | | { |
| | | printf("%s() get invalid arguments\n", __FUNCTION__); |
| | | pthread_exit(NULL); |
| | | } |
| | | |
| | | printf("Thread workder 1 [%ld] start running...\n", pthread_self()); |
| | | |
| | | while(1) |
| | | { |
| | | printf("+++: %s before shared_var++: %d\n", __FUNCTION__, *ptr); |
| | | *ptr += 1; |
| | | sleep(2); |
| | | printf("+++: %s after sleep shared_var: %d\n", __FUNCTION__, *ptr); |
| | | } |
| | | |
| | | printf("Thread workder 1 exit...\n"); |
| | | |
| | | return NULL; |
| | | } |
| | | |
| | | void *thread_worker2(void *args) |
| | | { |
| | | int *ptr = (int *)args; |
| | | |
| | | if( !args ) |
| | | { |
| | | printf("%s() get invalid arguments\n", __FUNCTION__); |
| | | pthread_exit(NULL); |
| | | } |
| | | |
| | | printf("Thread workder 2 [%ld] start running...\n", pthread_self()); |
| | | |
| | | while(1) |
| | | { |
| | | printf("---: %s before shared_var++: %d\n", __FUNCTION__, *ptr); |
| | | *ptr += 1; |
| | | sleep(2); |
| | | printf("---: %s after sleep shared_var: %d\n", __FUNCTION__, *ptr); |
| | | } |
| | | |
| | | printf("Thread workder 2 exit...\n"); |
| | | |
| | | return NULL; |
| | | } |
New file |
| | |
| | | #include <stdio.h> |
| | | #include <string.h> |
| | | #include <errno.h> |
| | | #include <stdlib.h> |
| | | #include <unistd.h> |
| | | #include <pthread.h> |
| | | |
| | | void *thread_worker1(void *args); |
| | | void *thread_worker2(void *args); |
| | | |
| | | typedef struct worker_ctx_s |
| | | { |
| | | int shared_var; |
| | | pthread_mutex_t lock; |
| | | } worker_ctx_t; |
| | | |
| | | int main(int argc, char **argv) |
| | | { |
| | | worker_ctx_t worker_ctx; |
| | | pthread_t tid; |
| | | pthread_attr_t thread_attr; |
| | | |
| | | worker_ctx.shared_var = 1000; |
| | | pthread_mutex_init(&worker_ctx.lock, NULL); |
| | | |
| | | |
| | | if( pthread_attr_init(&thread_attr) ) |
| | | { |
| | | printf("pthread_attr_init() failure: %s\n", strerror(errno)); |
| | | return -1; |
| | | } |
| | | |
| | | if( pthread_attr_setstacksize(&thread_attr, 120*1024) ) |
| | | { |
| | | printf("pthread_attr_setstacksize() failure: %s\n", strerror(errno)); |
| | | return -1; |
| | | } |
| | | |
| | | if( pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED) ) |
| | | { |
| | | printf("pthread_attr_setdetachstate() failure: %s\n", strerror(errno)); |
| | | return -1; |
| | | } |
| | | |
| | | pthread_create(&tid, &thread_attr, thread_worker1, &worker_ctx); |
| | | printf("Thread worker1 tid[%ld] created ok\n", tid); |
| | | |
| | | pthread_create(&tid, &thread_attr, thread_worker2, &worker_ctx); |
| | | printf("Thread worker2 tid[%ld] created ok\n", tid); |
| | | |
| | | while(1) |
| | | { |
| | | printf("Main/Control thread shared_var: %d\n", worker_ctx.shared_var); |
| | | sleep(10); |
| | | } |
| | | |
| | | pthread_mutex_destroy(&worker_ctx.lock); |
| | | } |
| | | |
| | | void *thread_worker1(void *args) |
| | | { |
| | | worker_ctx_t *ctx = (worker_ctx_t *)args; |
| | | |
| | | if( !args ) |
| | | { |
| | | printf("%s() get invalid arguments\n", __FUNCTION__); |
| | | pthread_exit(NULL); |
| | | } |
| | | |
| | | printf("Thread workder 1 [%ld] start running...\n", pthread_self()); |
| | | |
| | | while(1) |
| | | { |
| | | pthread_mutex_lock(&ctx->lock); |
| | | |
| | | printf("+++: %s before shared_var++: %d\n", __FUNCTION__, ctx->shared_var); |
| | | ctx->shared_var ++; |
| | | sleep(2); |
| | | printf("+++: %s after sleep shared_var: %d\n", __FUNCTION__, ctx->shared_var); |
| | | |
| | | pthread_mutex_unlock(&ctx->lock); |
| | | |
| | | sleep(1); |
| | | } |
| | | |
| | | printf("Thread workder 1 exit...\n"); |
| | | |
| | | return NULL; |
| | | } |
| | | |
| | | void *thread_worker2(void *args) |
| | | { |
| | | worker_ctx_t *ctx = (worker_ctx_t *)args; |
| | | |
| | | if( !args ) |
| | | { |
| | | printf("%s() get invalid arguments\n", __FUNCTION__); |
| | | pthread_exit(NULL); |
| | | } |
| | | |
| | | printf("Thread workder 2 [%ld] start running...\n", pthread_self()); |
| | | |
| | | while(1) |
| | | { |
| | | if(0 != pthread_mutex_trylock(&ctx->lock) ) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | printf("---: %s before shared_var++: %d\n", __FUNCTION__, ctx->shared_var); |
| | | ctx->shared_var ++; |
| | | sleep(2); |
| | | printf("---: %s after sleep shared_var: %d\n", __FUNCTION__, ctx->shared_var); |
| | | |
| | | pthread_mutex_unlock(&ctx->lock); |
| | | |
| | | sleep(1); |
| | | } |
| | | |
| | | printf("Thread workder 2 exit...\n"); |
| | | |
| | | return NULL; |
| | | } |