【笔记】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;
}

猜你喜欢

转载自www.cnblogs.com/qiu00/p/12368176.html
今日推荐