【笔记】Linux进程间同步和进程绑定至特定cpu
#define _GNU_SOURCE #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <pthread.h> #include <sys/socket.h> #include <arpa/inet.h> #include <sys/mman.h> #include <sys/epoll.h> #include <sys/sysinfo.h> #include <sched.h> #include <stdlib.h> typedef struct mtx { pthread_mutex_t mutex; pthread_mutexattr_t mutexattr; } mtx; int main() { //获取cpu数量 printf( "get_nprocs_conf = %d, get_nprocs = %d\n", get_nprocs_conf(), get_nprocs() ); mtx* mm; //内存映射,匿名,进程间共享内存 mm=(mtx*)mmap( NULL, sizeof(mtx), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0 ); //初始化互斥锁属性 pthread_mutexattr_init(&mm->mutexattr); pthread_mutexattr_setpshared(&mm->mutexattr, PTHREAD_PROCESS_SHARED); //设置互斥锁进程间共享,所有进程都能使用这个锁 pthread_mutex_init( &mm->mutex, &mm->mutexattr ); //初始化互斥锁 int socFd=socket( AF_INET, SOCK_STREAM, 0 ); int fgetFd = fcntl( socFd, F_GETFL ); fgetFd|=O_NONBLOCK; fcntl( socFd, F_SETFL, fgetFd ); struct sockaddr_in sock; sock.sin_family=AF_INET; sock.sin_addr.s_addr=inet_addr( "127.0.0.1" ); sock.sin_port=htons(8888); bind( socFd, ( struct sockaddr* )&sock, sizeof(sock) ); listen( socFd, 36 ); int epolFd = epoll_create( 2000 ); struct epoll_event epEvent; epEvent.events = EPOLLIN | EPOLLET; epEvent.data.fd = socFd; epoll_ctl( epolFd, EPOLL_CTL_ADD, socFd, &epEvent ); pid_t pid = fork(); cpu_set_t mask; int num=0; if(pid!=0) { CPU_SET( num, &mask ); //设置亲和力,父进程绑定到CPU0,taskset -p parent_pid_t 结果为1 01 } else { ++num; CPU_SET(num, &mask); //子进程绑定到CPU1,taskset -p child_pid_t 结果为2 10 } //设置进程亲和力,线程使用pthread_setaffinity_np() if(sched_setaffinity( 0, sizeof(mask), &mask ) == -1) { printf( "sched_setaffinity, pid = %d\n",pid ); } struct epoll_event arrEvent[200]; while( 1 ) { int size = epoll_wait( epolFd, arrEvent, 200, -1 ); for(int i=0; i<size; ++i) { if(arrEvent[i].data.fd==socFd) { if( pthread_mutex_trylock( &mm->mutex ) == 0 ) { printf("ppid = %d, pid = %d, locked\n", getppid(), getpid()); struct sockaddr_in client; socklen_t clilen=sizeof(client); int fd = accept( socFd, ( struct sockaddr * )&client, &clilen ); if( fd>0 ) { fgetFd = -1; fgetFd = fcntl( fd, F_GETFL ); fgetFd|=O_NONBLOCK; fcntl( fd, F_SETFL, fgetFd ); struct epoll_event eve; eve.events=EPOLLIN | EPOLLET; eve.data.fd=fd; epoll_ctl( epolFd, EPOLL_CTL_ADD, fd, &eve ); } pthread_mutex_unlock( &mm->mutex ); } } else { char buf[1024]={ 0 }; while(1) { int len=read( arrEvent[i].data.fd, buf, sizeof(buf) ); if(len<=0) { break; } printf("ppid = %d, pid = %d, \n", getppid(), getpid()); write(arrEvent[i].data.fd, buf, len); } epoll_ctl( epolFd, EPOLL_CTL_DEL, arrEvent[i].data.fd, NULL ); close( arrEvent[i].data.fd ); } } } pthread_mutex_destroy( &mm->mutex ); pthread_mutexattr_destroy( &mm->mutexattr ); munmap( ( void* )mm, sizeof( mtx ) ); close( socFd ); return 0; }