免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2439 | 回复: 2
打印 上一主题 下一主题

[操作系统] 多线程程序运行产生的进程个数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-07-11 16:17 |只看该作者 |倒序浏览

遇到一个诡异的问题,main程序启动后启三个线程,然后main函数while(1)。

通过ps命令查看应该仅仅会出现同名进程4个才对,但是出现了五个?

下面的是程序,使用shell脚本运行起来,因为是demo所以shell极其简单。

有没有兄弟留意过这个情况的?有什么解释没有,感激涕淋!!!
  1. #!/bin/sh

  2. echo "Start Openplat Demo..."

  3. /devinfo/package/openplatform_demo/openplatform_demo &
复制代码
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/ipc.h>
  4. #include <sys/msg.h>
  5. #include <errno.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <signal.h>
  10. #include <stdbool.h>
  11. #include <pthread.h>

  12. #define OPEN_PLAT_FLASH_BASE_PATH                "/devinfo"
  13. #define OPEN_APP_BASE_PATH                                "/devinfo/package"
  14. #define OPEN_APP_NAME                                        "openplatform_demo"

  15. //#define OPEN_PLAT_FLASH_BASE_PATH                "/mnt/mmc01"
  16. //#define OPEN_APP_BASE_PATH                                "/mnt/mmc01/package"

  17. #define OPEN_PLATFORM_MSG_IPCKEY                0x010

  18. #define OPEN_PLATFORM_MSG_PRI_SET                                1                // 参数设置接收消息类型
  19. #define OPEN_PLATFORM_MSG_PRI_SET_RESP                        2                // 参数设置应答消息类型
  20. #define OPEN_PLATFORM_MSG_PRI_GET                                3                // 参数获取接收消息类型
  21. #define OPEN_PLATFORM_MSG_PRI_GET_RESP                        4                // 参数获取应答消息类型
  22. #define OPEN_PLATFORM_MSG_PRI_UPLOAD_LICENSE        5                // license 数据接收消息类型
  23. #define OPEN_PLATFORM_MSG_PRI_UPLOAD_LICENSE_RESP        6        // license 导入应答消息类型

  24. #define OK                0
  25. #define ERROR        -1

  26. #define TRUE        1
  27. #define FALSE        0

  28. typedef int BOOL;

  29. typedef struct
  30. {
  31.         long mtype;
  32.         char buffer[8*1024];
  33. }msgbuf_ext;

  34. BOOL terminated = FALSE;

  35. /**@param[in] msqid: 消息队列描述符
  36.   *@param[in] buf:        消息队列缓冲区
  37.   *@param[in] cmd: IPC_STAT:该命令用来获取消息队列信息,返回的信息存贮在buf指向的msqid结构中;
  38.                                   IPC_SET:该命令用来设置消息队列的属性,要设置的属性存储在buf指向的msqid结构中;可设置属性包括:msg_perm.uid、msg_perm.gid、msg_perm.mode以及msg_qbytes,同时,也影响msg_ctime成员。
  39.                                   IPC_RMID:删除msqid标识的消息队列;
  40. */
  41. static int msg_ctl(int msqid, int cmd, struct msqid_ds *buf, char* appname)
  42. {
  43.         if(msgctl(msqid, cmd, 0) < 0)
  44.         {
  45.                 fprintf(stderr, "<%s %s LINE %d>msgctl failed [%s]!!\n", __FILE__, __FUNCTION__, __LINE__, strerror(errno));
  46.                 return ERROR;
  47.         }
  48.        
  49.         return OK;
  50. }

  51. /*
  52. *@brief 创建一个消息队列或者获取一个消息队列的描述符
  53. *@param[in]  appname: 第三方应用程序名称,用于构造创建消息队列的path
  54. *@param[in]  b_creat: TRUE 表示创建一个消息队列,FALSE: 表示获取消息队列描述符
  55. *@return ERROR 错误,成功,消息队列描述符
  56. */
  57. static int create_msgq(char* appname, BOOL b_creat)
  58. {
  59.         char path[128];
  60.         key_t key = -1;
  61.         int msgid;
  62.        
  63.         if(appname == NULL)
  64.         {
  65.                 fprintf(stderr, "create_msgq input is null!!!\n");
  66.                 return ERROR;
  67.         }

  68.         memset(path, 0, sizeof(path));
  69.         sprintf(path, "%s/%s", OPEN_APP_BASE_PATH, appname);
  70.        
  71.         key = ftok(path, OPEN_PLATFORM_MSG_IPCKEY);

  72.         fprintf(stderr, "create_msgq GET path \"%s\" , key [%d]!\n", path, key);
  73.         // 获取消息队列描述符
  74.         msgid = msgget(key, IPC_CREAT);
  75.        
  76.         if(msgid == -1)
  77.         {       
  78.                 fprintf(stderr, "create_msgq msgget Failed        [%s]!!!!\n", strerror(errno));
  79.                 return ERROR;
  80.         }
  81.         return msgid;
  82. }

  83. static int send_msg(int msqid, msgbuf_ext *msgp, size_t msgsz, int msgflag, char* appname)
  84. {
  85.         int ret = 0;
  86.        
  87.         if(msgp == NULL)
  88.         {
  89.                 fprintf(stderr, "send_msg input is err!!\n");
  90.                 return ERROR;
  91.         }
  92.        
  93.         ret = msgsnd(msqid, msgp, msgsz, msgflag);
  94.         if(ret < 0)
  95.         {
  96.                 fprintf(stderr, "send_msg msgsnd failed!!\n");
  97.                 return ERROR;
  98.         }
  99.         return OK;
  100. }

  101. static int recv_msg(int msqid, msgbuf_ext *msgp, size_t msgsz, long msgtype, int msgflag, char* appname)
  102. {
  103.         int ret = 0;
  104.        
  105.         if(msgp == NULL)
  106.         {
  107.                 fprintf(stderr, "recv_msg input is err!!\n");
  108.                 return ERROR;
  109.         }
  110.        
  111.         ret = msgrcv(msqid, msgp, msgsz, msgtype, msgflag);
  112.         if(ret < 0)
  113.         {
  114.                 fprintf(stderr, "recv_msg msgsnd failed  ret %d\n", ret);
  115.                 return ERROR;
  116.         }

  117.         return OK;
  118. }
  119. static void signal_handler(int sig, siginfo_t *siginfo, void* opaque)
  120. {
  121.         (void)opaque;
  122.         fprintf(stderr, "Signal was received: %s. Pid: %d. Uid: %d.\n", strsignal(sig), siginfo->si_pid, siginfo->si_uid);
  123.         if (sig == SIGINT || sig == SIGTERM)
  124.         {
  125.                 terminated = true;
  126.         }
  127.         else if(sig == SIGUSR2)
  128.         {
  129.                 // 恢复默认值信号
  130.                 fprintf(stderr, "@@@@@@simple reset app param!!!!\n");
  131.         }
  132. }

  133. static void signal_handler_init()
  134. {
  135.         struct sigaction sigact;
  136.         memset(&sigact, 0, sizeof(struct sigaction));  
  137.         sigact.sa_flags         = SA_SIGINFO;  
  138.         sigact.sa_sigaction = &signal_handler;
  139.         sigemptyset(&sigact.sa_mask);
  140.         sigaddset(&sigact.sa_mask, SIGINT);
  141.         sigaddset(&sigact.sa_mask, SIGTERM);
  142.         sigaddset(&sigact.sa_mask, SIGABRT);
  143.        
  144.         if (sigprocmask(SIG_UNBLOCK, &sigact.sa_mask, NULL) != 0)
  145.         {
  146.                 fprintf(stderr, "Sigprocmask failed. Error: %s\n", strerror(errno));
  147.                 exit(EXIT_FAILURE);   
  148.         }
  149.         if (sigaction(SIGINT, &sigact, NULL) != 0)
  150.         {
  151.                 fprintf(stderr, "Can't handle SIGINT. Error: %s\n", strerror(errno));
  152.                 exit(EXIT_FAILURE);  
  153.         }
  154.         if (sigaction(SIGTERM, &sigact, NULL) != 0)
  155.         {
  156.                 fprintf(stderr, "Can't handle SIGTERM. Error: %s\n", strerror(errno));
  157.                 exit(EXIT_FAILURE);
  158.         }
  159.         if (sigaction(SIGABRT, &sigact, NULL) != 0)
  160.         {  
  161.                 fprintf(stderr, "Can't handle SIGABRT. Error: %s\n", strerror(errno));
  162.                 exit(EXIT_FAILURE);  
  163.         }
  164. }

  165. static void openplatform_get_param_fun(void)
  166. {
  167.         int msgid;
  168.         msgbuf_ext msg;
  169.        
  170.         memset(&msg, 0, sizeof(msg));
  171.        
  172.         msgid = create_msgq(OPEN_APP_NAME, FALSE);
  173.         if(msgid < 0)
  174.         {
  175.                 fprintf(stderr, "%s create_msgq failed!!!\n", __FUNCTION__);
  176.                 exit(EXIT_FAILURE);
  177.         }
  178.        
  179.         while(1)
  180.         {
  181.                 memset(&msg, 0, sizeof(msg));
  182.                 msg.mtype = OPEN_PLATFORM_MSG_PRI_GET;
  183.                 if(recv_msg(msgid, &msg, sizeof(msg.buffer), OPEN_PLATFORM_MSG_PRI_GET, 0, OPEN_APP_NAME) == ERROR)
  184.                 {
  185.                         /* In general, here will be blocked, so usually will not enter here */
  186.                         fprintf(stderr, "%s recv_msg failed [%s]!!!\n", __FUNCTION__, strerror(errno));
  187.                         usleep(20000);
  188.                         exit(EXIT_FAILURE);
  189.                 }
  190.                 if(strlen(msg.buffer) == 0)
  191.                 {
  192.                         usleep(20000);
  193.                         continue;
  194.                 }
  195.                
  196.                 fprintf(stderr, "%s recv [%s]\n", __FUNCTION__, msg.buffer);

  197.                 if(strcmp(msg.buffer, "GetConfig") == 0)
  198.                 {
  199.                         /* Do something */
  200.                         memset(&msg, 0, sizeof(msg));
  201.                         msg.mtype = OPEN_PLATFORM_MSG_PRI_GET_RESP;
  202.                         sprintf(msg.buffer, "%s", "I have get \"GetConfig\" request!");
  203.                         if(send_msg(msgid, &msg, strlen(msg.buffer), 0, OPEN_APP_NAME) == ERROR)
  204.                         {
  205.                                 fprintf(stderr, "%s send_msg failed!!!\n", __FUNCTION__);
  206.                                 continue;
  207.                         }
  208.                 }
  209.                 else
  210.                 {
  211.                         fprintf(stderr, "%s Recv msg is err!!!\n", __FUNCTION__);
  212.                 }
  213.         }
  214. }
  215. static void openplatform_set_param_fun(void)
  216. {
  217.         int msgid;
  218.         msgbuf_ext msg;
  219.        
  220.         memset(&msg, 0, sizeof(msg));
  221.        
  222.         msgid = create_msgq(OPEN_APP_NAME, FALSE);
  223.         if(msgid < 0)
  224.         {
  225.                 fprintf(stderr, "%s create_msgq failed!!!\n", __FUNCTION__);
  226.                 exit(EXIT_FAILURE);
  227.         }
  228.        
  229.         while(1)
  230.         {
  231.                 memset(&msg, 0, sizeof(msg));
  232.                 msg.mtype = OPEN_PLATFORM_MSG_PRI_SET;
  233.                 if(recv_msg(msgid, &msg, sizeof(msg.buffer), OPEN_PLATFORM_MSG_PRI_SET, 0, OPEN_APP_NAME) == ERROR)
  234.                 {
  235.                         /* In general, here will be blocked, so usually will not enter here */
  236.                         fprintf(stderr, "%s recv_msg failed  [%s]!!!\n", __FUNCTION__, strerror(errno));
  237.                         usleep(20000);
  238.                         exit(EXIT_FAILURE);
  239.                 }
  240.                 if(strlen(msg.buffer) == 0)
  241.                 {
  242.                         usleep(20000);
  243.                         continue;
  244.                 }
  245.                
  246.                 fprintf(stderr, "%s recv [%s]\n", __FUNCTION__, msg.buffer);

  247.                 if(strncmp(msg.buffer, "SetConfig", strlen("SetConfig")) == 0)
  248.                 {
  249.                         /* Do something */
  250.                         memset(&msg, 0, sizeof(msg));
  251.                         msg.mtype = OPEN_PLATFORM_MSG_PRI_SET_RESP;
  252.                         sprintf(msg.buffer, "%s", "OK");
  253.                         if(send_msg(msgid, &msg, strlen(msg.buffer), 0, OPEN_APP_NAME) == ERROR)
  254.                         {
  255.                                 fprintf(stderr, "send_msg failed!!!\n");
  256.                                 continue;
  257.                         }
  258.                 }
  259.                 else
  260.                 {
  261.                         fprintf(stderr, "%s Recv msg is err!!!\n", __FUNCTION__);
  262.                 }
  263.         }
  264. }

  265. static void openplatform_license_upload_fun(void)
  266. {
  267.         int msgid;
  268.         msgbuf_ext msg;
  269.        
  270.         memset(&msg, 0, sizeof(msg));
  271.        
  272.         msgid = create_msgq(OPEN_APP_NAME, FALSE);
  273.         if(msgid < 0)
  274.         {
  275.                 fprintf(stderr, "%s create_msgq failed!!!\n", __FUNCTION__);
  276.                 exit(EXIT_FAILURE);
  277.         }
  278.        
  279.         while(1)
  280.         {
  281.                 memset(&msg, 0, sizeof(msg));
  282.                 msg.mtype = OPEN_PLATFORM_MSG_PRI_UPLOAD_LICENSE;
  283.                 if(recv_msg(msgid, &msg, sizeof(msg.buffer), OPEN_PLATFORM_MSG_PRI_UPLOAD_LICENSE, 0, OPEN_APP_NAME) == ERROR)
  284.                 {
  285.                         /* In general, here will be blocked, so usually will not enter here */
  286.                         fprintf(stderr, "%s recv_msg failed  [%s]!!!\n", __FUNCTION__, strerror(errno));
  287.                         usleep(20000);
  288.                         exit(EXIT_FAILURE);
  289.                 }
  290.                 if(strlen(msg.buffer) == 0)
  291.                 {
  292.                         usleep(20000);
  293.                         continue;
  294.                 }
  295.                
  296.                 fprintf(stderr, "%s recv [%s]\n", __FUNCTION__, msg.buffer);

  297.                 if(strncmp(msg.buffer, "uploadLicense", strlen("uploadLicense")) == 0)
  298.                 {
  299.                         /* Do something */
  300.                         memset(&msg, 0, sizeof(msg));
  301.                         msg.mtype = OPEN_PLATFORM_MSG_PRI_UPLOAD_LICENSE_RESP;
  302.                         sprintf(msg.buffer, "%s", "OK");
  303.                         if(send_msg(msgid, &msg, strlen(msg.buffer), 0, OPEN_APP_NAME) == ERROR)
  304.                         {
  305.                                 fprintf(stderr, "send_msg failed!!!\n");
  306.                                 continue;
  307.                         }
  308.                 }
  309.                 else
  310.                 {
  311.                         fprintf(stderr, "%s Recv msg is err!!!\n", __FUNCTION__);
  312.                 }
  313.         }
  314. }


  315. int main()
  316. {
  317.         pthread_t set_pthread_id = -1;
  318.         pthread_t get_pthread_id = -1;
  319.         pthread_t license_pthread_id = -1;
  320.         int err = -1;
  321.         pthread_attr_t attri;
  322.        
  323.         memset(&attri, 0, sizeof(attri));
  324.        
  325.         signal_handler_init();
  326.        
  327.         /* Initialization thread attribute */
  328.         pthread_attr_init(&attri);       
  329.        
  330.         /* Set to separate threads, thread end of the release of their own resources, other properties with default values */
  331.         err = pthread_attr_setdetachstate(&attri, PTHREAD_CREATE_DETACHED);
  332.         if(err != 0)
  333.         {
  334.                 pthread_attr_destroy(&attri);
  335.                 exit(EXIT_FAILURE);
  336.         }

  337.         err = pthread_create(&get_pthread_id, &attri, (void*)openplatform_get_param_fun, NULL);
  338.         if(err != 0)
  339.         {
  340.                 fprintf(stderr, "<openplatform_get_param_fun> pthread creat failed [%s]!\n", strerror(errno));
  341.                 exit(EXIT_FAILURE);
  342.         }

  343.         err = pthread_create(&set_pthread_id, &attri, (void*)openplatform_set_param_fun, NULL);
  344.         if(err != 0)
  345.         {
  346.                 fprintf(stderr, "<openplatform_set_param_fun> pthread creat failed [%s]!\n", strerror(errno));
  347.                 exit(EXIT_FAILURE);
  348.         }
  349.        
  350.         err = pthread_create(&license_pthread_id, &attri, (void*)openplatform_license_upload_fun, NULL);
  351.         if(err != 0)
  352.         {
  353.                 fprintf(stderr, "<openplatform_license_upload_fun> pthread creat failed [%s]!\n", strerror(errno));
  354.                 exit(EXIT_FAILURE);
  355.         }
  356.         while(!terminated)
  357.         {
  358.                 sleep(1);
  359.                 //fprintf(stderr, "open platform demo app!!\n");
  360.         }
  361.         return;
  362. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2014-07-11 16:46 |只看该作者
自己顶顶

另外还有一个疑问,怎么区分main和由main启动的线程?

名称都一样的

当然理论上来说进程号也是一种方式。
  1.   719 root      268m S    {worker.14} /home/centaurus
  2.   723 root         0 SW   [kworker/u:1]
  3.   748 root         0 SW   [kworker/0:0]
  4.   781 root      268m S    {ipc_upnpworker} /home/centaurus
  5.   785 root       668 S    /devinfo/package/openplatform_demo/openplatform_demo
  6.   786 root       668 S    /devinfo/package/openplatform_demo/openplatform_demo
  7.   787 root       668 S    /devinfo/package/openplatform_demo/openplatform_demo
  8.   788 root       668 S    /devinfo/package/openplatform_demo/openplatform_demo
  9.   789 root       668 S    /devinfo/package/openplatform_demo/openplatform_demo
  10.   790 root      268m S    /home/centaurus
  11.   791 root      1080 R    ps
  12. /proc #
复制代码

论坛徽章:
0
3 [报告]
发表于 2014-07-14 10:11 |只看该作者
没有兄弟遇到过这样的情况吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP