等到上一个流程实例完成 [英] wait until the previous instance of process finish

查看:71
本文介绍了等到上一个流程实例完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Linux C编程世界的新手,请耐心等待.找到了一些有关使用互斥量和信号量但与我的情况不完全匹配的进程间同步(同一进程但实例不同)的线程.我尝试关注它们并尝试创建一些示例,但是没有一个对我有用.

I am new to the world of Linux C Programming so request your patience. Found several threads about inter-process synchronization (same process but different instance) using mutex and semaphores but not exactly matching my case. I tried to follow them and tried to create few samples but none of them is working for me.

最后在此处发布以获取帮助.

Finally posting here to get some help.

我正在努力创建一个将通过以太网telnet会话执行的实用程序.如下面USAGE注释中所述,第一次调用将传递命令行参数-init,它将启动始终运行的线程.在-init之后,所有调用将具有-c:参数,并使用不同的十六进制代码指定.

I am working on to create a utility which will executed over Ethernet telnet session. As noted below in USAGE comment, 1st call will pass command line argument -init which will start a thread which will be running always. Following -init all call will have -c: argument specified with different hex code.

问题是,当一个实例仍在进行另一个调用时,它带有不同的-c:十六进制代码值.有时这会产生一个问题,即第二个调用返回的响应将返回到第一个调用. (这是因为当第一个命令仍在进行中时,终端设备正在快速发送对第二个命令的响应)

The problem is when one instance is still working on another call comes with different -c: hex code value. Sometimes this is creating a problem that the response returned by second call gets returned to the 1st call. (This is because the end device is sending response to 2nd command quickly while 1st command is still in-progress)

寻找一些伪代码或参考来帮助我同步部分代码,以防止在收到第一条命令的响应之前发送第二条命令.

Looking for some psudo code or reference which help me synchronize the part of code which can prevent sending 2nd command before receiving response of 1st command.

希望我能正确解释.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <ctype.h>

static volatile sig_atomic_t isRunning = 1;

/* Signal handler */
void signal_handler(int signal) {
    switch (signal) {
    case SIGINT:
    case SIGTERM:
    case SIGQUIT:
        /* Graceful shutdown */
        isRunning = 0;
        break;
    default:
        break;
    }
}

void* random_generator(void* data) {
    fd_set readfd;
    struct timeval timeout;
    char buff[20];
    struct tm *sTm;

    do {
        time_t now = time(0);
        sTm = gmtime(&now);

        strftime(buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", sTm);
        printf("%s\n", buff);

        timeout.tv_sec = 1;
        timeout.tv_usec = 0;
        int ret = select(0, NULL, NULL, NULL, &timeout);
        printf("Select returned: %d\n", ret);

    } while (isRunning);

    printf("Exiting thread...");
    pthread_exit((void*) 0);
}

int main(int argc, char** argv) {
    /*
     * USAGE:
     * 1st command -> ./util -init
     * 2nd command -> ./util -c:<hexcode>
     * 3rd command -> ./util -c:<hexcode>
     * .......
     */
    pthread_t mythread;

    signal(SIGTERM, signal_handler);
    signal(SIGINT, signal_handler);
    signal(SIGQUIT, signal_handler);

    if (argc == 2)
        return 0;

    if (strcmp(argv[1], "-c:") == 0) {
        // TODO: Only one process should be executing this part at any point of time
        ...lock();
        int count = 0;
        do{
            printf("Processing...%d\n", count);
        }while(count++ < 30);
        ...unlock();
        return 0;
    } else if (strcmp(argv[1], "-init") == 0) {
        // always running thread
        printf("Starting thread...\n");
        int ret = pthread_create(&mythread, NULL, random_generator, (void*) NULL);
        if (ret)
            printf("Failed starting thread\n");
        else
            printf("Thread started\n");

        pthread_join(mythread, NULL);
    }
    return 0;
}

推荐答案

这是我通过实现进程间信号量使其工作的方式.希望它可以帮助某人节省时间并学到一些东西.下面是更新的代码.完美适用于Ubuntu 14.04 LTS.

This is how I got it working by implementing interprocess semaphore. Hopefully it will help somebody save their time and learn something. Below is the updated code. Perfectly working on Ubuntu 14.04 LTS.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <ctype.h>

static volatile sig_atomic_t isRunning = 1;
#define SEM_NAME "mutex2"
static sem_t *mutex;

/* Signal handler */
void signal_handler(int signal) {
    switch (signal) {
    case SIGINT:
    case SIGTERM:
    case SIGQUIT:
        /* Graceful shutdown */
        isRunning = 0;
        break;
    default:
        break;
    }
}

void* random_generator(void* data) {
    fd_set readfd;
    struct timeval timeout;
    char buff[20];
    struct tm *sTm;
    int rc;

    do {
        time_t now = time(0);
        sTm = gmtime(&now);

        strftime(buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", sTm);
        printf("%s\n", buff);

        timeout.tv_sec = 1;
        timeout.tv_usec = 0;
        int ret = select(0, NULL, NULL, NULL, &timeout);
        printf("Select returned: %d\n", ret);

    } while (isRunning);

    printf("Exiting thread...\n");
    pthread_exit((void*) 0);
}

int main(int argc, char** argv) {
    /*
     * USAGE:
     * 1st command -> ./util -init
     * 2nd command -> ./util -c:<hexcode>
     * 3rd command -> ./util -c:<hexcode>
     * .......
     */
    pthread_t mythread;
    int rc;

    signal(SIGTERM, signal_handler);
    signal(SIGINT, signal_handler);
    signal(SIGQUIT, signal_handler);

    if (argc != 2)
        return 1;

    if (strcmp(argv[1], "-c:") == 0) {
        // TODO: Only once process should be executing this part at any point of time
        mutex = sem_open(SEM_NAME, O_CREAT);
        if (mutex == SEM_FAILED) {
            printf("sem_open error - %d (%m)\n", errno);
            return 1;
        }
        printf("sem_open success\n");

        printf("calling sem_wait\n");
        rc = sem_wait(mutex);
        if(rc < 0){
            printf("sem_wait error - %d (%m)\n", errno);
            return 1;
        }

        int i;
        for (i = 0; i < 10; i++){
            printf("process %d %d\n", getpid(), i);
            sleep(1);
        }

        printf("sem_post calling\n");
        rc = sem_post(mutex);
        if(rc < 0){
            printf("sem_post error - %d (%m)\n", errno);
            return 1;
        }

        return 0;

    } else if (strcmp(argv[1], "-init") == 0) {

        // always running thread
        printf("Starting thread...\n");
        int ret = pthread_create(&mythread, NULL, random_generator, (void*) NULL);
        if (ret)
            printf("Failed starting thread\n");
        else
            printf("Thread started\n");

        // open semaphore
        mutex = sem_open(SEM_NAME, O_CREAT);
        if (mutex == SEM_FAILED) {
            printf("sem_open error - %d (%m)\n", errno);
            sem_close(mutex);
            sem_unlink(SEM_NAME);
            return 1;
        }
        printf("sem_open success\n");

        rc = sem_init(mutex, 1, 1);
        if(rc < 0){
            printf("sem_init error - %d (%m)\n", errno);
            sem_close(mutex);
            sem_unlink(SEM_NAME);
            return 1;
        }
        printf("sem_init success\n");

        // join thread
        pthread_join(mythread, NULL);

        printf("Unlink semaphore...\n");
        rc = sem_close(mutex);
        if(rc < 0){
                fprintf(stdout, "sem_close error - %d (%m)\n", errno);
        }
        rc = sem_unlink(SEM_NAME);
        if(rc < 0){
            printf("sem_unlink error - %d (%m)\n", errno);
        }
    }

    return 0;
}

下面是编译和执行命令,

Compile and execute commands are below,

  1. $ gcc util.c -o util -pthread
  2. 在1号航站楼上运行-$ ./util -init
  3. 在2,3,4号航站楼上运行-$ ./util -c:
  1. $ gcc util.c -o util -pthread
  2. On Terminal 1 run - $ ./util -init
  3. On Terminal 2,3,4 run - $ ./util -c:

这篇关于等到上一个流程实例完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆