{"id":1828,"date":"2019-01-20T11:25:26","date_gmt":"2019-01-20T03:25:26","guid":{"rendered":"https:\/\/www.yusian.com\/blog\/?p=1828"},"modified":"2020-12-02T11:32:03","modified_gmt":"2020-12-02T03:32:03","slug":"linux%e7%bc%96%e7%a8%8b-%e8%bf%9b%e7%a8%8b%e5%90%8c%e6%ad%a5","status":"publish","type":"post","link":"https:\/\/www.yusian.com\/blog\/cpp\/2019\/01\/20\/1125261828.html","title":{"rendered":"Linux\u7f16\u7a0b&#8211;\u8fdb\u7a0b\u540c\u6b65"},"content":{"rendered":"<h3>1\u3001pthread_mutex_t\u5b9e\u73b0\u8fdb\u7a0b\u9501<\/h3>\n<ul>\n<li>\u521b\u5efa\u8fdb\u7a0b\uff1afork<\/li>\n<li>\u5185\u5b58\u6620\u5c04\u533a\uff1ammap<\/li>\n<li>\u521b\u5efa\u4e92\u65a5\u9501\uff1apthread_mutex_init<\/li>\n<li>\u521b\u5efa\u4e92\u65a5\u9501\u5c5e\u6027\uff1apthread_mutexattr_init<\/li>\n<\/ul>\n<p>\u793a\u4f8b\u4ee3\u7801<!--more--><\/p>\n<pre><code class=\"language-c line-numbers\">#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;pthread.h&gt;\n#include &lt;sys\/mman.h&gt;\n#include &lt;sys\/wait.h&gt;\n#include &lt;fcntl.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;string.h&gt;\n\n\/\/ \u8fdb\u7a0b\u5171\u4eab\u6570\u636e\u6a21\u578b\nstruct model{\n    int num;\n    pthread_mutex_t mutex;\n    pthread_mutexattr_t attr;\n};\nint main(){\n    int length = sizeof(struct model);\n    \/*\n    int fd = open(\"temp.txt\", O_CREAT | O_RDWR, 0664);\n    if (fd &lt; 0){\n        perror(\"open error:\");\n        exit(1);\n    }\n    int ret = ftruncate(fd, length);\n    if (ret &lt; 0){\n        perror(\"ftruncate error\");\n        exit(1);\n    }\n    *\/\n    \/\/ \u521b\u5efa\u5171\u4eab\u6570\u636e\uff08\u5185\u5b58\u6620\u5c04\uff09\n    struct model *m = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);\n    if (m == MAP_FAILED){\n        perror(\"mmap error:\");\n        exit(1);\n    }\n    memset(m, 0, length);\n\n    \/\/ \u521d\u59cb\u5316mutex\u53camutexattr\n    pthread_mutexattr_init(&amp;m-&gt;attr);\n    \/\/ mutex\u9ed8\u8ba4\u72b6\u6001\u4e3a\u7ebf\u7a0b\u4e92\u65a5\uff0c\u901a\u8fc7attr\u8bbe\u7f6e\u4e3a\u8fdb\u7a0b\u4e92\u65a5\n    pthread_mutexattr_setpshared(&amp;m-&gt;attr, PTHREAD_PROCESS_SHARED);\n    pthread_mutex_init(&amp;m-&gt;mutex, &amp;m-&gt;attr);\n    pthread_mutexattr_destroy(&amp;m-&gt;attr);\n    \/\/ \u751f\u4ea7\u968f\u673a\u6570\u79cd\u5b50\n    srand(time(NULL));\n    \/\/ \u521b\u5efa\u65b0\u8fdb\u7a0b\n    pid_t pid = fork();\n    if (pid &lt; 0){\n        perror(\"fork error:\");\n        exit(1);\n    }else if (pid == 0){\n        \/\/ \u7236\u8fdb\u7a0b\n        int i = 10;\n        while(i--){\n            pthread_mutex_lock(&amp;m-&gt;mutex);\n            m-&gt;num += 1;\n            printf(\"parent ---- %d\\n\", m-&gt;num);\n            pthread_mutex_unlock(&amp;m-&gt;mutex);\n            usleep(rand()%500000);\n        }\n        \/\/ \u56de\u6536\u5b50\u8fdb\u7a0b\u3001\u4e92\u65a5\u9501\u3001\u5185\u5b58\u6620\u5c04\n        wait(NULL);\n        pthread_mutex_destroy(&amp;m-&gt;mutex);\n        munmap(m, length);\n    }else{    \/\/ \u5b50\u8fdb\u7a0b\n        int i = 10;\n        while(i--){\n            pthread_mutex_lock(&amp;m-&gt;mutex);\n            m-&gt;num += 2;\n            printf(\"child  ---- %d\\n\", m-&gt;num);\n            pthread_mutex_unlock(&amp;m-&gt;mutex);\n            usleep(rand()%500000);\n        }\n    }\n    return 0;\n}\n<\/code><\/pre>\n<p>\u6267\u884c\u7ed3\u679c<\/p>\n<pre><code class=\"language-cmd line-numbers\">parallels@ubuntu:~\/Linux\/process$ .\/mutex.out\nchild  ---- 2\nparent ---- 3\nparent ---- 4\nchild  ---- 6\nchild  ---- 8\nparent ---- 9\nchild  ---- 11\nparent ---- 12\nparent ---- 13\nchild  ---- 15\nchild  ---- 17\nparent ---- 18\nchild  ---- 20\nparent ---- 21\nchild  ---- 23\nparent ---- 24\nchild  ---- 26\nparent ---- 27\nchild  ---- 29\nparent ---- 30\nparallels@ubuntu:~\/Linux\/process$\n<\/code><\/pre>\n<h3>2\u3001fcntl\u5b9e\u73b0\u6587\u4ef6\u9501<\/h3>\n<ul>\n<li>F_SETLK\uff1a\u8bbe\u7f6e\u6587\u4ef6\u9501\uff08trylock\uff09<\/li>\n<li>F_SETLKW\uff1a\u8bbe\u7f6e\u6587\u4ef6\u9501\uff08lock\uff09W->wait<\/li>\n<li>F_GETLK\uff1a\u83b7\u53d6\u6587\u4ef6\u9501<\/li>\n<\/ul>\n<pre><code class=\"language-c line-numbers\">int fcntl(int fd, int cmd, ... \/* arg *\/ );\n\nF_SETLK, F_SETLKW, and F_GETLK are used to acquire, release, and test for the existence of record locks (also known as byte-range, file-segment, or\n       file-region locks).  The third argument, lock, is a pointer to a structure that has at least the following fields (in unspecified order).\n\n           struct flock {\n               ...\n               short l_type;    \/* Type of lock: F_RDLCK,\n                                   F_WRLCK, F_UNLCK *\/\n               short l_whence;  \/* How to interpret l_start:\n                                   SEEK_SET, SEEK_CUR, SEEK_END *\/\n               off_t l_start;   \/* Starting offset for lock *\/\n               off_t l_len;     \/* Number of bytes to lock *\/\n               pid_t l_pid;     \/* PID of process blocking our lock\n                                   (set by F_GETLK and F_OFD_GETLK) *\/\n               ...\n           };\n<\/code><\/pre>\n<p>\u793a\u4f8b\u4ee3\u7801\uff1a<\/p>\n<pre><code class=\"language-c line-numbers\">#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;fcntl.h&gt;\n\nint main(int argc, char* argv[]){\n    \/\/ \u8981\u6c42\u4f20\u5165\u9700\u8981\u52a0\u9501\u7684\u6587\u4ef6\u8def\u5f84\n    if (argc &lt; 2){\n        printf(\"e.g: .\/a.out filename\\n\");\n        exit(1);\n    }\n    const char* filename = argv[1];\n    \/\/ \u521d\u59cb\u5316\u6587\u4ef6\u9501\u7ed3\u6784\u4f53\n    struct flock lock;\n    \/\/lock.l_type = F_RDLCK;     \/\/ \u52a0\u9501\u7c7b\u578b\uff08\u8bfb\u6216\u5199\uff09\n    lock.l_type = F_WRLCK;\n    lock.l_whence = SEEK_SET;    \/\/ \u52a0\u9501\u4f4d\u7f6e\uff08\u5f53\u524d\u4f4d\u7f6e\u3001\u8d77\u59cb\u4f4d\u7f6e\u3001\u672b\u5c3e\u4f4d\u7f6e\uff09\n    lock.l_start = 0;            \/\/ \u5f00\u59cb\u4f4d\u7f6e\u504f\u79fb\u91cf\n    lock.l_len = 0;              \/\/ \u52a0\u9501\u957f\u5ea6(\u5355\u4f4d\u5b57\u8282)\uff0c0\u5219\u5168\u90e8\u52a0\u9501\n    int fd = open(filename, O_RDWR);\n    if (fd &lt; 0){\n        perror(\"open error\");\n        exit(1);\n    }\n    \/\/ \u8bbe\u7f6e\u6587\u4ef6\u9501:SETLKW\uff0c\u963b\u585e\u5f62\u5f0f\u8bbe\u7f6e\uff08\u52a0\u9501\u8fd8\u662f\u89e3\u9501\u53d6\u51b3\u4e8e\u7ed3\u6784\u4f53lock\u4e2d\u7684\u503c\uff09\n    fcntl(fd, F_SETLKW, &amp;lock);\n    printf(\"file is locked with 'F_RDLCK'\\n\");\n    sleep(10);\n    \/\/ \u4fee\u6539\u7ed3\u6784\u4f53\u53c2\u6570\n    lock.l_type = F_UNLCK;\n    \/\/ \u8bbe\u7f6e\u6587\u4ef6\u9501\uff08\u89e3\u9501\uff09\n    fcntl(fd, F_SETLKW, &amp;lock);\n    printf(\"file is unlock...\\n\u201d);\n    \/\/ \u5173\u95ed\u6587\u4ef6\n    close(fd);\n    return 0;\n}\n<\/code><\/pre>\n<p>\u6267\u884c\u7ed3\u679c\uff1a<br \/>\n* \u5728\u9501\u4e3a\u8bfb\u7684\u60c5\u51b5\u4e0b\uff0c\u591a\u8fdb\u7a0b\u53ef\u4ee5\u5bf9\u5355\u4e2a\u6587\u4ef6\u540c\u65f6\u64cd\u4f5c\uff1b<br \/>\n* \u5728\u9501\u4e3a\u5199\u7684\u60c5\u51b5\u4e0b\uff0c\u591a\u8fdb\u7a0b\u4f1a\u88ab\u963b\u585e\u7b49\u5f85\uff0c\u53ea\u6709\u4e0a\u4e00\u4e2a\u8fdb\u7a0b\u89e3\u9501\u540e\uff0c\u4e0b\u4e00\u4e2a\u624d\u80fd\u8fdb\u884c\u52a0\u9501<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1\u3001pthread_mutex_t\u5b9e\u73b0\u8fdb\u7a0b\u9501 \u521b\u5efa\u8fdb\u7a0b\uff1afork \u5185\u5b58\u6620\u5c04\u533a\uff1ammap \u521b\u5efa\u4e92\u65a5\u9501\uff1apthread_mutex_init \u521b\u5efa\u4e92\u65a5\u9501\u5c5e\u6027\uff1apthread_mutexattr_init \u793a\u4f8b\u4ee3\u7801<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[88],"tags":[310,318],"class_list":["post-1828","post","type-post","status-publish","format-standard","hentry","category-cpp","tag-linux","tag-318"],"_links":{"self":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/posts\/1828","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/comments?post=1828"}],"version-history":[{"count":0,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/posts\/1828\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/media?parent=1828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/categories?post=1828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/tags?post=1828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}